From 30b8aa0b03c8e14fb92716348b0f31df6dba4f82 Mon Sep 17 00:00:00 2001 From: alexpolo1 Date: Thu, 1 May 2025 20:36:32 +0200 Subject: [PATCH] version1 --- get_oauth_token.php | 182 ++++++++++++++++++++++++++++++++ index.html | 36 +++++++ index.php | 203 ++++++++++++++++++++++++++++++++++++ login.php | 39 +++++++ logout.php | 7 ++ send.php | 249 ++++++++++++++++++++++++++++++++++++++++++++ style.css | 121 +++++++++++++++++++++ 7 files changed, 837 insertions(+) create mode 100644 get_oauth_token.php create mode 100644 index.html create mode 100644 index.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 send.php create mode 100644 style.css diff --git a/get_oauth_token.php b/get_oauth_token.php new file mode 100644 index 0000000..0e54a00 --- /dev/null +++ b/get_oauth_token.php @@ -0,0 +1,182 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2020 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * Get an OAuth2 token from an OAuth2 provider. + * * Install this script on your server so that it's accessible + * as [https/http]:////get_oauth_token.php + * e.g.: http://localhost/phpmailer/get_oauth_token.php + * * Ensure dependencies are installed with 'composer install' + * * Set up an app in your Google/Yahoo/Microsoft account + * * Set the script address as the app's redirect URL + * If no refresh token is obtained when running this file, + * revoke access to your app and run the script again. + */ + +namespace PHPMailer\PHPMailer; + +/** + * Aliases for League Provider Classes + * Make sure you have added these to your composer.json and run `composer install` + * Plenty to choose from here: + * @see https://oauth2-client.thephpleague.com/providers/thirdparty/ + */ +//@see https://github.com/thephpleague/oauth2-google +use League\OAuth2\Client\Provider\Google; +//@see https://packagist.org/packages/hayageek/oauth2-yahoo +use Hayageek\OAuth2\Client\Provider\Yahoo; +//@see https://github.com/stevenmaguire/oauth2-microsoft +use Stevenmaguire\OAuth2\Client\Provider\Microsoft; +//@see https://github.com/greew/oauth2-azure-provider +use Greew\OAuth2\Client\Provider\Azure; + +if (!isset($_GET['code']) && !isset($_POST['provider'])) { + ?> + + +
+

Select Provider

+ +
+ +
+ +
+ +
+

Enter id and secret

+

These details are obtained by setting up an app in your provider's developer console. +

+

ClientId:

+

ClientSecret:

+

TenantID (only relevant for Azure):

+ +
+ + + $clientId, + 'clientSecret' => $clientSecret, + 'redirectUri' => $redirectUri, + 'accessType' => 'offline' +]; + +$options = []; +$provider = null; + +switch ($providerName) { + case 'Google': + $provider = new Google($params); + $options = [ + 'scope' => [ + 'https://mail.google.com/' + ] + ]; + break; + case 'Yahoo': + $provider = new Yahoo($params); + break; + case 'Microsoft': + $provider = new Microsoft($params); + $options = [ + 'scope' => [ + 'wl.imap', + 'wl.offline_access' + ] + ]; + break; + case 'Azure': + $params['tenantId'] = $tenantId; + + $provider = new Azure($params); + $options = [ + 'scope' => [ + 'https://outlook.office.com/SMTP.Send', + 'offline_access' + ] + ]; + break; +} + +if (null === $provider) { + exit('Provider missing'); +} + +if (!isset($_GET['code'])) { + //If we don't have an authorization code then get one + $authUrl = $provider->getAuthorizationUrl($options); + $_SESSION['oauth2state'] = $provider->getState(); + header('Location: ' . $authUrl); + exit; + //Check given state against previously stored one to mitigate CSRF attack +} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { + unset($_SESSION['oauth2state']); + unset($_SESSION['provider']); + exit('Invalid state'); +} else { + unset($_SESSION['provider']); + //Try to get an access token (using the authorization code grant) + $token = $provider->getAccessToken( + 'authorization_code', + [ + 'code' => $_GET['code'] + ] + ); + //Use this to interact with an API on the users behalf + //Use this to get a new access token if the old one expires + echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken()); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..465bbd9 --- /dev/null +++ b/index.html @@ -0,0 +1,36 @@ + + + + + + WM Ware Form + + + +
+

WM Ware Form

+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..4c614bf --- /dev/null +++ b/index.php @@ -0,0 +1,203 @@ + + + + + VM Configurator + + + +
+

VM Configurator

+
+ + +
+ + +
+ +
+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + Small VM + +

2 vCPU, 4 GB RAM, 50 GB HDD

+
+
+ + Medium VM + +

4 vCPU, 8 GB RAM, 50 GB HDD

+
+
+ + Big VM + +

8 vCPU, 16 GB RAM, 50 GB HDD

+
+
+ +
+

Configuration Summary

+

vCPU: -

+

RAM: - GB

+

HDD: - GB

+
+ + +
+
+ Logout +
+
+ + + + \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..894e1b6 --- /dev/null +++ b/login.php @@ -0,0 +1,39 @@ + + + + + Login + + +

Login

+ $error

"; ?> +
+ + +
+ + +
+ +
+ + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..eba5cc9 --- /dev/null +++ b/logout.php @@ -0,0 +1,7 @@ + diff --git a/send.php b/send.php new file mode 100644 index 0000000..d57f1bd --- /dev/null +++ b/send.php @@ -0,0 +1,249 @@ + + + Alex VM Project + + + + + ['vcpus' => 2, 'ram' => 4], + 'medium' => ['vcpus' => 4, 'ram' => 8], + 'big' => ['vcpus' => 8, 'ram' => 16] + ]; + + $vCPUs = isset($sizeMapping[$Size]) ? $sizeMapping[$Size]['vcpus'] : null; + $Ram_Value = isset($sizeMapping[$Size]) ? $sizeMapping[$Size]['ram'] * 1024 : null; // Convert GB to MB + + // Set HDD value to always be 50GB + $HDD_Value = 50 * 1024; // Convert GB to MB + + // Check for required fields + if (!$VM_Name || $vCPUs === null || $Ram_Value === null || !$Domain) { + echo "Error: Missing or invalid input data."; + exit; + } + + // Function to check if a VM name already exists in NetBox + function checkIfVmExists($vmName, $netboxApiUrl, $apiToken) { + $vmsApiUrl = rtrim($netboxApiUrl, '/') . '/?name=' . urlencode($vmName); + + // Query NetBox for the VM name + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $vmsApiUrl); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Token ' . $apiToken + ]); + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($httpCode === 200) { + $vms = json_decode($response, true); + if (!empty($vms['results'])) { + return true; // VM with the same name exists + } + } else { + echo "Error: Failed to check VM name. HTTP Code: $httpCode
"; + echo "Response: $response
"; + } + + return false; // VM does not exist + } + + // Check if the VM name already exists + if (checkIfVmExists($VM_Name, $netboxApiUrl, $apiToken)) { + echo "Error: A VM with the name '$VM_Name' already exists in NetBox."; + exit; + } + + // Function to get or create a tag in NetBox + function getOrCreateTag($tagName, $netboxApiUrl, $apiToken) { + $tagsApiUrl = 'http://192.168.1.144:80/api/extras/tags/'; + + // Check if the tag exists + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $tagsApiUrl . '?name=' . urlencode($tagName)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Token ' . $apiToken + ]); + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($httpCode === 200) { + $tags = json_decode($response, true); + if (!empty($tags['results'])) { + return $tags['results'][0]['id']; // Return the ID of the existing tag + } + } + + // If the tag doesn't exist, create it + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $tagsApiUrl); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['name' => $tagName])); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Authorization: Token ' . $apiToken + ]); + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($httpCode === 201) { + $tag = json_decode($response, true); + return $tag['id']; // Return the ID of the newly created tag + } + + return null; // Return null if the tag couldn't be created + } + + // Get or create the domain tag + $domainTagId = getOrCreateTag($Domain, $netboxApiUrl, $apiToken); + if (!$domainTagId) { + echo "Error: Failed to retrieve or create the domain tag."; + exit; + } + + // Function to create a virtual disk in NetBox + function createDisk($vmId, $diskName, $diskSize, $netboxApiUrl, $apiToken) { + $disksApiUrl = 'http://192.168.1.144:80/api/virtualization/virtual-disks/'; + + // Prepare disk data + $diskData = [ + 'virtual_machine' => $vmId, + 'name' => $diskName, + 'size' => $diskSize // Size in MB + ]; + + // Initialize cURL + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $disksApiUrl); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($diskData)); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Authorization: Token ' . $apiToken + ]); + + // Execute cURL request + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($httpCode === 201) { + echo "Disk '$diskName' created successfully.
"; + } else { + echo "Failed to create disk '$diskName'. HTTP Code: $httpCode
"; + echo "Response: $response
"; + } + } + + // Prepare data for NetBox API to create the VM + $data = [ + 'name' => $VM_Name, + 'vcpus' => $vCPUs, + 'memory' => $Ram_Value, + 'status' => 'active', // Adjust as needed + 'cluster' => 1, // Replace with the appropriate cluster ID + 'tags' => [$domainTagId] // Include the domain tag ID + ]; + + // Initialize cURL to create the VM + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $netboxApiUrl); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Authorization: Token ' . $apiToken + ]); + + // Execute cURL request to create the VM + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($response === false) { + echo 'cURL Error: ' . curl_error($ch); + } else { + if ($httpCode === 201) { + echo "VM created successfully in NetBox.
"; + $vm = json_decode($response, true); + $vmId = $vm['id']; // Get the VM ID from the response + + // Create OS Disk + createDisk($vmId, 'osdisk', 60 * 1024, $netboxApiUrl, $apiToken); + + // Create Data Disk + createDisk($vmId, 'datadisk', 50 * 1024, $netboxApiUrl, $apiToken); + } else { + echo "Failed to create VM in NetBox. HTTP Code: $httpCode
"; + echo "Response: $response
"; + } + } + + curl_close($ch); + ?> +
+

Processing Your VM Configuration...

+

You will be redirected to the front page in 20 seconds.

+
+ Logout +
+
+ + diff --git a/style.css b/style.css new file mode 100644 index 0000000..8b3dea6 --- /dev/null +++ b/style.css @@ -0,0 +1,121 @@ + body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background-color: #f5f7fa; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + margin: 0; + padding: 20px; + } + + .form-container { + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); + padding: 30px; + width: 100%; + max-width: 450px; + } + + h2 { + color: #2c3e50; + margin-top: 0; + margin-bottom: 25px; + text-align: center; + font-weight: 600; + } + + .form-group { + margin-bottom: 20px; + } + + label { + display: block; + margin-bottom: 8px; + color: #4a5568; + font-weight: 500; + font-size: 0.95rem; + } + + input, select { + width: 100%; + padding: 12px; + margin: 12px; + border: 1px solid #ddd; + border-radius: 6px; + font-size: 1rem; + transition: border-color 0.3s, box-shadow 0.3s; + box-sizing: border-box; + } + + input:focus, select:focus { + border-color: #4299e1; + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.2); + outline: none; + } + + select { + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%234a5568' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 12px center; + background-size: 16px; + padding-right: 40px; + } + + button { + background-color: #4299e1; + color: white; + border: none; + border-radius: 6px; + padding: 12px 24px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + width: 100%; + transition: background-color 0.3s, transform 0.1s; + } + + button:hover { + background-color: #3182ce; + } + + button:active { + transform: translateY(1px); + } + + /* Optional: Add some animation effects */ + @keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } + } + + .form-container { + animation: fadeIn 0.5s ease-out; + } + + /* Add validation styling */ + input:invalid, select:invalid { + border-color: #e53e3e; + } + + /* Add success message styling */ + .success-message { + background-color: #c6f6d5; + color: #2f855a; + padding: 12px; + border-radius: 6px; + margin-bottom: 20px; + text-align: center; + } + + /* Add error message styling */ + .error-message { + background-color: #fed7d7; + color: #c53030; + padding: 12px; + border-radius: 6px; + margin-bottom: 20px; + text-align: center; + } \ No newline at end of file