Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.91 KB | None | 0 0
  1. <?php
  2. /**
  3. Pterodactyl WHMCS Module
  4.  
  5. The MIT License (MIT)
  6.  
  7. Copyright (c) 2016 Emmet Young
  8.  
  9. Permission is hereby granted, free of charge, to any person obtaining a copy
  10. of this software and associated documentation files (the "Software"), to deal
  11. in the Software without restriction, including without limitation the rights
  12. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. copies of the Software, and to permit persons to whom the Software is
  14. furnished to do so, subject to the following conditions:
  15.  
  16. The above copyright notice and this permission notice shall be included in all
  17. copies or substantial portions of the Software.
  18.  
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  25. SOFTWARE.
  26. **/
  27.  
  28. if (!defined("WHMCS")) {
  29. die("This file cannot be accessed directly");
  30. }
  31.  
  32. //Define the current version of this module
  33. $MODULE_VERSION = "1.1";
  34.  
  35. use Illuminate\Database\Capsule\Manager as Capsule;
  36.  
  37. /**
  38. * Makes a formatted API call to Pterodactyl utilizing CURL.
  39. *
  40. * Values returned here are the result of the API called to the
  41. * pterodactyl panel.
  42. *
  43. * @return array
  44. */
  45. function pterodactyl_api_call($publickey, $privatekey, $url, $type, array $data = NULL )
  46. {
  47. $curl = curl_init();
  48. curl_setopt($curl, CURLOPT_URL, $url);
  49. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  50. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type);
  51. curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
  52. curl_setopt($curl, CURLOPT_USERAGENT, "Pterodactyl WHMCS Plugin/". $MODULE_VERSION);
  53.  
  54. if(isset($data))
  55. {
  56. $data = json_encode($data);
  57. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  58. }
  59.  
  60. $hmac = hash_hmac('sha256', $url . $data, $privatekey, true);
  61.  
  62. $headers = array("Authorization: Bearer " . $publickey . '.' . base64_encode($hmac),
  63. "Content-Type: application/json; charset=utf-8");
  64.  
  65. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  66.  
  67. $curldata = curl_exec($curl);
  68.  
  69. if($curldata == false)
  70. {
  71. logModuleCall(
  72. 'pterodactylWHMCS',
  73. 'CURL ERROR',
  74. curl_error($curl),
  75. ''
  76. );
  77. }
  78.  
  79. $responsedata = json_decode($curldata, true);
  80. $responsedata['status_code'] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  81.  
  82. curl_close($curl);
  83.  
  84. logModuleCall(
  85. 'pterodactylWHMCS',
  86. $url,
  87. isset($data) ? print_r($data, true) : '',
  88. print_r($responsedata, true)
  89. );
  90.  
  91. return $responsedata;
  92. }
  93.  
  94. /**
  95. * Define module related meta data.
  96. *
  97. * Values returned here are used to determine module related abilities and
  98. * settings.
  99. *
  100. * @see http://docs.whmcs.com/Provisioning_Module_Meta_Data_Parameters
  101. *
  102. * @return array
  103. */
  104. function pterodactyl_MetaData()
  105. {
  106. return array(
  107. 'DisplayName' => 'Pterodactyl',
  108. 'APIVersion' => '1.1', // Use API Version 1.1
  109. 'RequiresServer' => true, // Set true if module requires a server to work
  110. );
  111. }
  112.  
  113. /**
  114. * Define product configuration options.
  115. *
  116. * @return array
  117. */
  118. function pterodactyl_ConfigOptions()
  119. {
  120. return array(
  121. 'memory' => array(
  122. 'Type' => 'text',
  123. 'Size' => '10',
  124. 'Default' => '1024',
  125. 'Description' => 'Total memory (in MB) to assign to the server',
  126. ),
  127. 'swap' => array(
  128. 'Type' => 'text',
  129. 'Size' => '10',
  130. 'Default' => '256',
  131. 'Description' => 'Total swap (in MB) to assign to the server',
  132. ),
  133. 'cpu' => array(
  134. 'Type' => 'text',
  135. 'Size' => '10',
  136. 'Default' => '50',
  137. 'Description' => 'Cpu limit, value is as a percentage of each core. One core being 100%.',
  138. ),
  139. 'io' => array(
  140. 'Type' => 'text',
  141. 'Size' => '10',
  142. 'Default' => '500',
  143. 'Description' => 'Block IO adjustment number.',
  144. ),
  145. 'disk' => array(
  146. 'Type' => 'text',
  147. 'Size' => '10',
  148. 'Default' => '1024',
  149. 'Description' => 'Total disk space (in MB) to assign to the server.',
  150. ),
  151. 'location' => array(
  152. 'Type' => 'text',
  153. 'Size' => '10',
  154. 'Default' => '1',
  155. 'Description' => 'ID of location in which server should be created.',
  156. ),
  157. 'service' => array(
  158. 'Type' => 'text',
  159. 'Size' => '10',
  160. 'Default' => '1',
  161. 'Description' => 'ID of the service this server is using.',
  162. ),
  163. 'option' => array(
  164. 'Type' => 'text',
  165. 'Size' => '10',
  166. 'Default' => '1',
  167. 'Description' => 'ID of the specific service option this server is using.',
  168. ),
  169. 'startup' => array(
  170. 'Type' => 'text',
  171. 'Size' => '25',
  172. 'Default' => '',
  173. 'Description' => 'The startup parameters this server is using.',
  174. ),
  175. 'auto_deploy' => array(
  176. 'Type' => 'yesno',
  177. 'Default' => 'yes',
  178. 'Description' => 'Tick to enable auto deploy. You do not need the below options with auto deploy enabled.',
  179. ),
  180. 'node' => array(
  181. 'Type' => 'text',
  182. 'Size' => '25',
  183. 'Default' => '',
  184. 'Description' => 'ID of the node to assign the server to (must be apart of the specified location id).',
  185. ),
  186. 'allocation' => array(
  187. 'Type' => 'text',
  188. 'Size' => '25',
  189. 'Default' => '',
  190. 'Description' => 'The allocation ID to use for the server (only if not using auto_deploy, and not using ip and port).',
  191. ),
  192. 'pack' => array(
  193. 'Type' => 'text',
  194. 'Size' => '25',
  195. 'Default' => '0',
  196. 'Description' => 'Pack ID number, leave as 0 if you dont want to utilize it.',
  197. ),
  198. 'description' => array(
  199. 'Type' => 'text',
  200. 'Size' => '100',
  201. 'Default' => '{{servicename}} server for user {{userid}}',
  202. 'Description' => 'Description to be used for server creation.',
  203. )
  204. );
  205. }
  206.  
  207. /**
  208. * Handle the creation of our user table.
  209. */
  210. function create_user_table()
  211. {
  212. if(!Capsule::schema()->hasTable('tbl_pterodactylproduct'))
  213. {
  214. Capsule::schema()->create(
  215. 'tbl_pterodactylproduct',
  216. function ($table) {
  217. $table->increments('id');
  218. $table->integer('client_id');
  219. $table->integer('service_id');
  220. $table->integer('user_id');
  221. $table->integer('server_id');
  222. }
  223. );
  224. }
  225. }
  226.  
  227. /**
  228. * Generate a random string.
  229. */
  230. function generate_username()
  231. {
  232. $returnable = false;
  233. while (!$returnable) {
  234. $generated = str_random(8);
  235. if (preg_match('/[A-Z]+[a-z]+[0-9]+/', $generated)) {
  236. $returnable = true;
  237. }
  238. }
  239. return $generated;
  240. }
  241.  
  242. /**
  243. * Handle overiding of variables.
  244. */
  245. function handle_overide(array $params, $overide_variable, $config_option, $data = NULL)
  246. {
  247. if (isset($params['configoptions'][$overide_variable]) && $params['configoptions'][$overide_variable] != "")
  248. return $params['configoptions'][$overide_variable];
  249. else if (isset($params['customfields'][$overide_variable]) && $params['customfields'][$overide_variable] != "")
  250. return $params['customfields'][$overide_variable];
  251. else if (isset($params[$config_option]) && $params[$config_option] != "")
  252. return $params[$config_option];
  253. else
  254. return $data;
  255. }
  256.  
  257. /**
  258. * Provision a new instance of a product/service.
  259. *
  260. * Attempt to provision a new instance of a given product/service. This is
  261. * called any time provisioning is requested inside of WHMCS. Depending upon the
  262. * configuration, this can be any of:
  263. * * When a new order is placed
  264. * * When an invoice for a new order is paid
  265. * * Upon manual request by an admin user
  266. *
  267. * @param array $params common module parameters
  268. *
  269. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  270. *
  271. * @return string "success" or an error message
  272. */
  273. function pterodactyl_CreateAccount(array $params)
  274. {
  275. try {
  276. $newAccount = false;
  277.  
  278. create_user_table();
  279.  
  280. $searching = true;
  281. $current_page = 1;
  282. while($searching)
  283. {
  284. $users = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/users?page=' . $current_page, 'GET');
  285. foreach($users['data'] as $user)
  286. {
  287. if ($user['attributes']['email'] !== $params['clientsdetails']['email'])
  288. continue;
  289.  
  290. $user_id = $user['id'];
  291. $searching = false;
  292. break;
  293. }
  294.  
  295. if($current_page == $users['meta']['pagination']['total_pages'])
  296. {
  297. $searching = false;
  298. } else {
  299. $current_page++;
  300. }
  301. }
  302.  
  303. if(!isset($user_id))
  304. {
  305. //Begin by creating the user on the panel side
  306. $data = array("email" => $params['clientsdetails']['email'],
  307. "username" => generate_username(),
  308. "name_first" => $params['clientsdetails']['firstname'],
  309. "name_last" => $params['clientsdetails']['lastname'],
  310. "root_admin" => false,
  311. "password" => $params['password']
  312. );
  313.  
  314. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/users', 'POST', $data);
  315.  
  316. if($response['status_code'] != 200)
  317. {
  318. return "Error during create account: Response: ".$response['error'] + " Status Code: ".$response['status_code'];
  319. }
  320.  
  321. $user_id = $response['data']['id'];
  322. $newAccount = true;
  323. }
  324.  
  325. $server_name = generate_username();
  326.  
  327. //Now get the panel to create a new server for our new user.
  328. $new_server = array("name" => $server_name."_".$params['serviceid'],
  329. "user_id" => $user_id,
  330. "auto_deploy" => $params['configoption10'] === 'on' ? true : false
  331. );
  332.  
  333. //Handle overiding of service ID, we need to handle this before grabbing the service
  334. $new_server['service_id'] = handle_overide($params, 'service_id', 'configoption7');
  335.  
  336. $service = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/services/'.$new_server['service_id'].'?include=options.variables', 'GET');
  337.  
  338. $replaceableFields = array('{{servicename}}', '{{userid}}');
  339. $dataToReplaceWith = array($service['data']['attributes']['name'], $user_id);
  340.  
  341. $new_server['memory'] = handle_overide($params, 'memory', 'configoption1' );
  342. $new_server['swap'] = handle_overide($params, 'swap', 'configoption2' );
  343. $new_server['cpu'] = handle_overide($params, 'cpu', 'configoption3' );
  344. $new_server['io'] = handle_overide($params, 'io', 'configoption4' );
  345. $new_server['disk'] = handle_overide($params, 'disk', 'configoption5' );
  346. $new_server['pack_id'] = handle_overide($params, 'pack_id', 'configoption13');
  347. $new_server['location_id'] = handle_overide($params, 'location_id', 'configoption6' );
  348. $new_server['option_id'] = handle_overide($params, 'option_id', 'configoption8' );
  349. $new_server['startup'] = handle_overide($params, 'startup', 'configoption9', $service['data']['attributes']['startup']);
  350. $new_server['description'] = str_replace($replaceableFields, $dataToReplaceWith, $params['configoption14']);
  351.  
  352. //We need to loop through every option to handle environment variables for our specified option
  353. foreach($service['included'] as $option)
  354. {
  355.  
  356. if ($option['type'] !== 'variable')
  357. continue;
  358.  
  359. if ($new_server['option_id'] == $option['attributes']['option_id'])
  360. {
  361. $new_server["env_".$option['attributes']['env_variable']] = handle_overide($params, $option['attributes']['env_variable'], NULL, $option['attributes']['default_value']);
  362. }
  363. }
  364.  
  365. //If auto deploy is enabled, we need additional information
  366. if (!$new_server['auto_deploy'])
  367. {
  368. $new_server['node_id'] = handle_overide($params, 'node_id', 'configoption11');
  369. $new_server["allocation_id"] = handle_overide($params, 'allocation_id', 'configoption12');
  370. }
  371.  
  372. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/servers?include=allocations', 'POST', $new_server);
  373.  
  374. if($response['status_code'] != 200)
  375. {
  376. return "Error during create server: Response Message: ".$response['error'] + " Status Code: ".$response['status_code'];
  377. }
  378.  
  379. $server_id = $response['data']['id'];
  380.  
  381. Capsule::table('tbl_pterodactylproduct')->insert(
  382. ['client_id' => $params['userid'],'service_id' => $params['serviceid'], 'user_id' => $user_id,'server_id' => $server_id]
  383. );
  384.  
  385. //Grab the admin ID, makes it easier to make calls to the API
  386. $adminid = Capsule::table('tbladmins')->where('disabled',0)->where('roleid',1)->pluck('id');
  387.  
  388. //Setup all the parameters we want to pass into the email
  389. $clientname = $params['clientsdetails']['fullname'];
  390. $panelurl = $params['serverhostname'];
  391. $clientemail = $params['clientsdetails']['email'];
  392. $clientpassword = $params['password'];
  393.  
  394. $clientId['clientid'] = $params['userid'];
  395. $clientServiceId['serviceid'] = $params['serviceid'];
  396.  
  397. //Call the WHMCS api to get client details, we need this to display the currency code
  398. $clientdetails = localAPI("getclientsdetails", $clientId, $adminid[0]);
  399. //Also call the WHMCS API to get the product details for the client
  400. $clientproducts = localAPI("getclientsproducts", $clientServiceId, $adminid[0]);
  401.  
  402. $service_product_name = $clientproducts['products']['product'][0]['name'];
  403. $service_payment_method = $clientproducts['products']['product'][0]['paymentmethodname'];
  404. $service_billing_cycle = $clientproducts['products']['product'][0]['billingcycle'];
  405. $service_next_due_date = $clientproducts['products']['product'][0]['nextduedate'] == "0000-00-00" ? "----" : $clientproducts['products']['product'][0]['nextduedate'];
  406. $service_recurring_amount = "$".$clientproducts['products']['product'][0]['recurringamount']." ".$clientdetails['currency_code'];
  407.  
  408. //Format the email for sending
  409. $email["customtype"] = "product";
  410. $email["customsubject"] = "New Product Information";
  411. $email["custommessage"] = "<p>Dear $clientname,</p>
  412. <p>Your order for <b>$service_product_name</b> has now been activated. Please keep this message for your records.</p>
  413. <p><b>Product/Service:</b> $service_product_name <br />
  414. <b>Payment Method:</b> $service_payment_method <br />
  415. <b>Amount:</b> $service_recurring_amount <br />
  416. <b>Billing Cycle:</b> $service_billing_cycle <br />
  417. <b>Next Due Date:</b> $service_next_due_date <br /> <br />
  418. <b>Panel Login URL:</b> <a href='$panelurl'>$panelurl</a><br />
  419. <b>Panel Login Email:</b> $clientemail <br />";
  420. if ($newAccount)
  421. {
  422. $email["custommessage"] .= "<b>Panel Login Password:</b> $clientpassword <br />";
  423. }
  424. else
  425. {
  426. $email["custommessage"] .= "<b>Panel Login Password:</b> Use pre-existing password. <br /><br />";
  427. }
  428.  
  429. foreach($response['included'] as $allocation)
  430. {
  431. $email["custommessage"] .= "<b>Server IP:</b> ".$allocation['attributes']['ip'].":".$allocation['attributes']['port']."<br />";
  432. if(isset($allocation['attributes']['ip_alias']))
  433. {
  434. $email["custommessage"] .= "<b>Server Alias:</b> ".$allocation['attributes']['ip_alias'].":".$allocation['attributes']['port']."<br />";
  435. }
  436. }
  437.  
  438. $email["custommessage"] .= "</p>
  439. <p>Thank you for choosing us.</p>";
  440.  
  441. $email["custommessage"] = preg_replace( "/\r|\n/", "", $email["custommessage"] );
  442.  
  443. $email["id"] = $params['serviceid'];
  444. localAPI("sendemail", $email, $adminid[0]);
  445.  
  446. } catch (Exception $e) {
  447. // Record the error in WHMCS's module log.
  448. logModuleCall(
  449. 'pterodactylWHMCS',
  450. __FUNCTION__,
  451. $params,
  452. $e->getMessage(),
  453. $e->getTraceAsString()
  454. );
  455.  
  456. return $e->getMessage();
  457. }
  458.  
  459. return 'success';
  460. }
  461.  
  462. /**
  463. * Test connection with the given server parameters.
  464. *
  465. * @return array
  466. */
  467. function pterodactyl_TestConnection(array $params)
  468. {
  469. try {
  470. $success = true;
  471. $errorMsg = '';
  472.  
  473. $nodes = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/nodes', 'GET', $data);
  474.  
  475. if ($nodes['status_code'] != 200)
  476. {
  477. $success = false;
  478. $errorMsg = 'Failed to connect to server, ensure your API keys are correct and your panel is running on a valid SSL Certificate. Failed with HTTP Status Code: ' + $nodes['status_code'];
  479. }
  480.  
  481. if ($nodes['meta']['pagination']['count'] <= 0)
  482. {
  483. $success = false;
  484. $errorMsg = 'No Nodes available, please setup a node before proceeding, otherwise this module will fail to work correctly.';
  485. }
  486.  
  487. } catch (Exception $e) {
  488. // Record the error in WHMCS's module log.
  489. logModuleCall(
  490. 'pterodactylWHMCS',
  491. __FUNCTION__,
  492. $params,
  493. $e->getMessage(),
  494. $e->getTraceAsString()
  495. );
  496. $success = false;
  497. $errorMsg = $e->getMessage();
  498. }
  499. return array(
  500. 'success' => $success,
  501. 'error' => $errorMsg,
  502. );
  503. }
  504.  
  505. function pterodactyl_get_client($serviceid)
  506. {
  507. return Capsule::table('tbl_pterodactylproduct')
  508. ->select('user_id', 'server_id')
  509. ->where('service_id', '=', $serviceid)
  510. ->first();
  511. }
  512.  
  513. /**
  514. * Suspend an instance of a product/service.
  515. *
  516. * Called when a suspension is requested. This is invoked automatically by WHMCS
  517. * when a product becomes overdue on payment or can be called manually by admin
  518. * user.
  519. *
  520. * @param array $params common module parameters
  521. *
  522. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  523. *
  524. * @return string "success" or an error message
  525. */
  526. function pterodactyl_SuspendAccount(array $params)
  527. {
  528. try {
  529. $client = pterodactyl_get_client($params['serviceid']);
  530.  
  531. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/servers/'.$client->server_id.'/suspend?action=suspend', 'PATCH');
  532.  
  533. if($response['status_code'] != 204)
  534. {
  535. return $response['error'] + " HTTP Status code: " + $response['status_code'] ;
  536. }
  537. } catch (Exception $e) {
  538. // Record the error in WHMCS's module log.
  539. logModuleCall(
  540. 'pterodactylWHMCS',
  541. __FUNCTION__,
  542. $params,
  543. $e->getMessage(),
  544. $e->getTraceAsString()
  545. );
  546.  
  547. return $e->getMessage();
  548. }
  549.  
  550. return 'success';
  551. }
  552.  
  553. /**
  554. * Un-suspend instance of a product/service.
  555. *
  556. * Called when an un-suspension is requested. This is invoked
  557. * automatically upon payment of an overdue invoice for a product, or
  558. * can be called manually by admin user.
  559. *
  560. * @param array $params common module parameters
  561. *
  562. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  563. *
  564. * @return string "success" or an error message
  565. */
  566. function pterodactyl_UnsuspendAccount(array $params)
  567. {
  568. try {
  569. $client = pterodactyl_get_client($params['serviceid']);
  570.  
  571. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/servers/'.$client->server_id."/suspend?action=unsuspend", 'PATCH');
  572.  
  573. if($response['status_code'] != 204)
  574. {
  575. return $response['error'] + " HTTP Status code: " + $response['status_code'];
  576. }
  577. } catch (Exception $e) {
  578. // Record the error in WHMCS's module log.
  579. logModuleCall(
  580. 'pterodactylWHMCS',
  581. __FUNCTION__,
  582. $params,
  583. $e->getMessage(),
  584. $e->getTraceAsString()
  585. );
  586.  
  587. return $e->getMessage();
  588. }
  589.  
  590. return 'success';
  591. }
  592.  
  593. /**
  594. * Terminate instance of a product/service.
  595. *
  596. * Called when a termination is requested. This can be invoked automatically for
  597. * overdue products if enabled, or requested manually by an admin user.
  598. *
  599. * @param array $params common module parameters
  600. *
  601. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  602. *
  603. * @return string "success" or an error message
  604. */
  605. function pterodactyl_TerminateAccount(array $params)
  606. {
  607. try {
  608. $client = pterodactyl_get_client($params['serviceid']);
  609.  
  610. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/servers/'.$client->server_id."/force", 'DELETE');
  611.  
  612. if($response['status_code'] != 204)
  613. {
  614. return $response['error'] + " HTTP Status code: " + $response['status_code'];
  615. }
  616.  
  617. Capsule::table('tbl_pterodactylproduct')
  618. ->where('service_id', '=', $client->service_id)
  619. ->delete();
  620.  
  621. } catch (Exception $e) {
  622. // Record the error in WHMCS's module log.
  623. logModuleCall(
  624. 'pterodactylWHMCS',
  625. __FUNCTION__,
  626. $params,
  627. $e->getMessage(),
  628. $e->getTraceAsString()
  629. );
  630.  
  631. return $e->getMessage();
  632. }
  633.  
  634. return 'success';
  635. }
  636.  
  637. /**
  638. * Change the password for an instance of a product/service.
  639. *
  640. * Called when a password change is requested. This can occur either due to a
  641. * client requesting it via the client area or an admin requesting it from the
  642. * admin side.
  643. *
  644. * This option is only available to client end users when the product is in an
  645. * active status.
  646. *
  647. * @param array $params common module parameters
  648. *
  649. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  650. *
  651. * @return string "success" or an error message
  652. */
  653. function pterodactyl_ChangePassword(array $params)
  654. {
  655. try {
  656. $client = pterodactyl_get_client($params['serviceid']);
  657.  
  658. $data = array("password" => $params['password'] );
  659.  
  660. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/users/'. $client->user_id, 'PUT', $data);
  661.  
  662. if($response['status_code'] != 200)
  663. {
  664. return $response['error'] + " HTTP Status code: " + $response['status_code'];
  665. }
  666.  
  667. } catch (Exception $e) {
  668. // Record the error in WHMCS's module log.
  669. logModuleCall(
  670. 'pterodactylWHMCS',
  671. __FUNCTION__,
  672. $params,
  673. $e->getMessage(),
  674. $e->getTraceAsString()
  675. );
  676.  
  677. return $e->getMessage();
  678. }
  679.  
  680. return 'success';
  681. }
  682.  
  683. /**
  684. * Upgrade or downgrade an instance of a product/service.
  685. *
  686. * Called to apply any change in product assignment or parameters. It
  687. * is called to provision upgrade or downgrade orders, as well as being
  688. * able to be invoked manually by an admin user.
  689. *
  690. * This same function is called for upgrades and downgrades of both
  691. * products and configurable options.
  692. *
  693. * @param array $params common module parameters
  694. *
  695. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  696. *
  697. * @return string "success" or an error message
  698. */
  699.  
  700. function pterodactyl_ChangePackage(array $params)
  701. {
  702. try {
  703. $client = pterodactyl_get_client($params['serviceid']);
  704.  
  705. $data = array("memory" => $params['configoption1'],
  706. "swap" => $params['configoption2'],
  707. "cpu" => $params['configoption3'],
  708. "io" => $params['configoption4'],
  709. "disk" => $params['configoption5'],
  710. );
  711.  
  712. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/servers/'. $client->server_id.'/build', 'PUT', $data);
  713.  
  714. if($response['status_code'] != 200)
  715. {
  716. return $response['error'] + " HTTP Status code: " + $response['status_code'];
  717. }
  718. } catch (Exception $e) {
  719. // Record the error in WHMCS's module log.
  720. logModuleCall(
  721. 'pterodactylWHMCS',
  722. __FUNCTION__,
  723. $params,
  724. $e->getMessage(),
  725. $e->getTraceAsString()
  726. );
  727.  
  728. return $e->getMessage();
  729. }
  730.  
  731. return 'success';
  732. }
  733.  
  734. /**
  735. * Admin services tab additional fields.
  736. *
  737. * Define additional rows and fields to be displayed in the admin area service
  738. * information and management page within the clients profile.
  739. *
  740. * Supports an unlimited number of additional field labels and content of any
  741. * type to output.
  742. *
  743. * @param array $params common module parameters
  744. *
  745. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  746. * @see pterodactyl_AdminServicesTabFieldsSave()
  747. *
  748. * @return array
  749. */
  750. function pterodactyl_AdminServicesTabFields(array $params)
  751. {
  752. try {
  753. $response = array();
  754.  
  755. return array(
  756. 'Memory' => $params['configoption1']."mb",
  757. 'Swap' => $params['configoption2']."mb",
  758. 'CPU' => $params['configoption3']."%",
  759. 'IO' => $params['configoption4'],
  760. 'Disk' => $params['configoption5']."mb",
  761. 'Last Access Date' => date("Y-m-d H:i:s", $response['lastLoginTimestamp']),
  762. );
  763. } catch (Exception $e) {
  764. // Record the error in WHMCS's module log.
  765. logModuleCall(
  766. 'pterodactylWHMCS',
  767. __FUNCTION__,
  768. $params,
  769. $e->getMessage(),
  770. $e->getTraceAsString()
  771. );
  772.  
  773. // In an error condition, simply return no additional fields to display.
  774. }
  775.  
  776. return array();
  777. }
  778.  
  779.  
  780. /**
  781. * Client area output logic handling.
  782. *
  783. * This function is used to define module specific client area output. It should
  784. * return an array consisting of a template file and optional additional
  785. * template variables to make available to that template.
  786. *
  787. * @param array $params common module parameters
  788. *
  789. * @see http://docs.whmcs.com/Provisioning_Module_SDK_Parameters
  790. *
  791. * @return array
  792. */
  793. function pterodactyl_ClientArea(array $params)
  794. {
  795. $requestedAction = isset($_REQUEST['customAction']) ? $_REQUEST['customAction'] : '';
  796.  
  797. $serviceAction = 'get_stats';
  798. $templateFile = 'templates/overview.tpl';
  799.  
  800. try {
  801. $client = pterodactyl_get_client($params['serviceid']);
  802.  
  803. $response = pterodactyl_api_call($params['serverusername'], $params['serverpassword'], $params['serverhostname'].'/api/admin/servers/'. $client->server_id . '?include=allocations', 'GET');
  804.  
  805. $serverip['ip'] = '';
  806. $serverip['ip_alias'] = '';
  807.  
  808. foreach($response['included'] as $allocation)
  809. {
  810.  
  811. $serverip['ip'][] .= $allocation['attributes']['ip'].":".$allocation['attributes']['port'] .", ";
  812. if(isset($allocation['attributes']['ip_alias']))
  813. {
  814. $serverip['ip_alias'] .= $allocation['attributes']['ip_alias'].":".$allocation['attributes']['port'] .", ";
  815. }
  816. }
  817.  
  818. return array(
  819. 'tabOverviewReplacementTemplate' => $templateFile,
  820. 'templateVariables' => array(
  821. 'panelhostname' => $params['serverhostname'],
  822. 'memory' => $params['configoption1']."mb",
  823. 'disk' => $params['configoption5']."mb",
  824. 'email' => $params['clientsdetails']['email'],
  825. 'server_ip' => $serverip['ip'],
  826. 'server_alias' => $serverip['ip_alias'],
  827. ),
  828. );
  829. } catch (Exception $e) {
  830. // Record the error in WHMCS's module log.
  831. logModuleCall(
  832. 'pterodactylWHMCS',
  833. __FUNCTION__,
  834. $params,
  835. $e->getMessage(),
  836. $e->getTraceAsString()
  837. );
  838. }
  839. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement