From 94f2ba3999f4e8a6b7771f2ba58bdbbb8179d783 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Tue, 2 Feb 2021 08:57:13 -0500 Subject: [PATCH 01/23] Update ProductsHelper.php @jazz7381 jazz7381 use count to use check return by ->get() Latest commit 359b574 on Dec 20, 2020 --- addons/vultr/helpers/ProductsHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/vultr/helpers/ProductsHelper.php b/addons/vultr/helpers/ProductsHelper.php index 08d579b..cd24f2c 100755 --- a/addons/vultr/helpers/ProductsHelper.php +++ b/addons/vultr/helpers/ProductsHelper.php @@ -25,7 +25,7 @@ private static function prepareConfigurableOptions($vultrAPI, $productID) { $checkIsset = DB::table('tblproductconfiglinks')->where('pid', $productID)->get(); - if ($checkIsset) + if (count($checkIsset) > 0) { return array('status' => false, 'message' => 'Product configurable options already exist!'); } @@ -116,7 +116,7 @@ public static function getProductConfigOptions($productID, $field = 'all', $defa public static function customFields($productID) { $result = DB::table('tblcustomfields')->where('fieldname', 'subid|Virtual machine ID')->where('type', 'product')->where('relid', $productID)->select('id')->get(); - if (!$result) + if (count($result) < 1) { DB::table('tblcustomfields')->insert(array('type' => 'product', 'relid' => $productID, 'fieldname' => 'subid|Virtual machine ID', 'fieldtype' => 'text', 'adminonly' => 'on')); return array('status' => true, 'reload' => true, 'message' => 'success'); From ddcc3c225ff35a5e76fbb29cc6fba423205cac3b Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Tue, 2 Feb 2021 08:58:46 -0500 Subject: [PATCH 02/23] Update main.controller.php Open use count to use check return by ->get() #101 --- servers/vultr/controller/main.controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/vultr/controller/main.controller.php b/servers/vultr/controller/main.controller.php index 90fe737..ad97a50 100755 --- a/servers/vultr/controller/main.controller.php +++ b/servers/vultr/controller/main.controller.php @@ -377,12 +377,12 @@ private function addVMCustomFields($SUBID) ->where('type', 'product') ->where('relid', $this->params['packageid']) ->where('fieldname', 'LIKE', 'subid|%')->get(); - if ($customField) + if (count($customField) > 0) { $customFieldValue = Capsule::table('tblcustomfieldsvalues') ->where('fieldid', $customField[0]->id) ->where('relid', $this->serviceID)->get(); - if ($customFieldValue) + if (count($customFieldValue) > 0) { $customFieldValue = Capsule::table('tblcustomfieldsvalues') ->where('fieldid', $customField[0]->id) From f75ad4e5b2cc61a021072c86ad1d42394458c2f7 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Tue, 2 Feb 2021 08:59:56 -0500 Subject: [PATCH 03/23] Update sshkeys.controller.php jazz7381 use count to use check return by ->get() --- servers/vultr/controller/sshkeys.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/controller/sshkeys.controller.php b/servers/vultr/controller/sshkeys.controller.php index e11189f..32f0e13 100755 --- a/servers/vultr/controller/sshkeys.controller.php +++ b/servers/vultr/controller/sshkeys.controller.php @@ -15,7 +15,7 @@ public function indexAction() if ($this->getVultrAPI()) { $allowKeys = Capsule::table('vultr_sshkeys')->where('client_id', $this->clientID)->get(); - if (empty($allowKeys)) + if (count($allowKeys) < 1) { return array(); } From 0930c85ef24efecf2992a01ddff3fefa1e190be2 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Tue, 2 Feb 2021 09:01:52 -0500 Subject: [PATCH 04/23] Update vultr.helper.php jazz7381 use count to use check return by ->get() --- servers/vultr/helper/vultr.helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/vultr/helper/vultr.helper.php b/servers/vultr/helper/vultr.helper.php index 240ae82..b6fa41f 100755 --- a/servers/vultr/helper/vultr.helper.php +++ b/servers/vultr/helper/vultr.helper.php @@ -490,7 +490,7 @@ public static function getAvailableIsos($isosList) public static function getUserScripts($clientID, $scripts) { $allowScripts = Capsule::table('vultr_scripts')->where('client_id', $clientID)->get(); - if (empty($allowScripts)) + if (count($allowScripts) < 1) { return array(); } @@ -521,7 +521,7 @@ public static function getUserScripts($clientID, $scripts) public static function getUserSSHKeys($clientID, $keys) { $allowKeys = Capsule::table('vultr_sshkeys')->where('client_id', $clientID)->get(); - if (empty($allowKeys)) + if (count($allowKeys) < 1) { return array(); } From 12fdacf0618e62b3b36762de61110c928bf92bac Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Wed, 3 Feb 2021 08:24:09 -0500 Subject: [PATCH 05/23] Create VultrAPI2.php start on converting api to v2 --- servers/vultr/vendor/VultrAPI2.php | 1097 ++++++++++++++++++++++++++++ 1 file changed, 1097 insertions(+) create mode 100644 servers/vultr/vendor/VultrAPI2.php diff --git a/servers/vultr/vendor/VultrAPI2.php b/servers/vultr/vendor/VultrAPI2.php new file mode 100644 index 0000000..f017d26 --- /dev/null +++ b/servers/vultr/vendor/VultrAPI2.php @@ -0,0 +1,1097 @@ +api_token = $token; + $this->cache_ttl = $cache_ttl; + $this->account = self::account_info(); + } + + /** + * Get Account info + * @see https://www.vultr.com/api/#tag/account + * @return mixed + */ + public function account_info() + { + return self::get('account'); + } + + /** + * Get OS list + * @see https://www.vultr.com/api/#operation/list-os + * @return mixed + */ + public function os_list() + { + return self::get('os'); + } + // needs done + public function os_change_list($subid) + { + return self::get('server/os_change_list', array('SUBID' => $subid)); + } + // needs done + public function os_change($subid, $osid) + { + return self::code('server/os_change', array('SUBID' => $subid, 'OSID' => $osid)); + } + + public function attach_iso($subid, $isoid) + { + return self::code('server/iso_attach', array('SUBID' => $subid, 'ISOID' => $isoid)); + } + + public function detach_iso($subid) + { + return self::code('server/iso_detach', array('SUBID' => $subid)); + } + + public function iso_status($subid) + { + return self::get('server/iso_status', array('SUBID' => $subid)); + } + + /** + * List available snapshots + * @see https://www.vultr.com/api/#snapshot_snapshot_list + * @return mixed + */ + public function snapshot_list() + { + return self::get('snapshot/list'); + } + + /** + * Destroy snapshot + * @see https://www.vultr.com/api/#snapshot_destroy + * @param int $snapshot_id + * @return int HTTP response code + */ + public function snapshot_destroy($snapshot_id) + { + $args = array('SNAPSHOTID' => $snapshot_id); + return self::code('snapshot/destroy', $args); + } + + /** + * Create snapshot + * @see https://www.vultr.com/api/#snapshot_create + * @param int $server_id + */ + public function snapshot_create($server_id, $description) + { + $args = array('SUBID' => $server_id, 'description' => $description); + return self::post('snapshot/create', $args); + } + + public function domain_create($domain, $serverIP) + { + $args = array('domain' => $domain, 'serverip' => $serverIP); + return self::code('dns/create_domain', $args); + } + + public function domain_delete($domain) + { + $args = array('domain' => $domain); + return self::code('dns/delete_domain', $args); + } + + /** + * List available ISO iamges + * @see https://www.vultr.com/api/#iso_list + * @return mixed Available ISO images + * */ + public function iso_list() + { + return self::get('iso/list'); + } + + public function dns_list() + { + return self::get('dns/list'); + } + + public function dns_records($domain) + { + return self::get('dns/records', array('domain' => $domain)); + } + + public function create_record($args) + { + return self::code('dns/create_record', $args); + } + + public function delete_record($args) + { + return self::code('dns/delete_record', $args); + } + + public function update_record($args) + { + return self::code('dns/update_record', $args); + } + + public function soa_update($args) + { + return self::code('dns/soa_update', $args); + } + + public function soa_info($args) + { + return self::get('dns/soa_info', $args); + } + + public function upgrade_plan_list($subid) + { + return self::get('server/upgrade_plan_list', array('SUBID' => $subid)); + } + + public function upgrade_plan($subid, $vpsplanid) + { + return self::code('server/upgrade_plan', array('SUBID' => $subid, 'VPSPLANID' => $vpsplanid)); + } + + /** + * List available applications + * @see https://www.vultr.com/api/#app_app_list + * @return mixed Available applications + * */ + public function app_list() + { + return self::get('app/list'); + } + + public function app_change_list($subid) + { + return self::get('server/app_change_list', array('SUBID' => $subid)); + } + + public function app_change($subid, $appid) + { + return self::code('server/app_change', array('SUBID' => $subid, 'APPID' => $appid)); + } + + /** + * List available plans + * @see https://www.vultr.com/api/#plans_plan_list + * @return mixed + */ + public function plans_list() + { + return self::get('plans/list'); + } + + /** + * List available regions + * @see https://www.vultr.com/api/#regions_region_list + * @return mixed + */ + public function regions_list() + { + return self::get('regions/list'); + } + + /** + * Determine region availability + * @see https://www.vultr.com/api/#regions_region_available + * @param int $datacenter_id + * @return mixed VPS plans available at given region + */ + public function regions_availability($datacenter_id) + { + $did = (int)$datacenter_id; + return self::get('regions/availability?DCID=' . $did); + } + + public function server_userData($server_id) + { + return self::get('server/get_user_data', array('SUBID' => $server_id)); + } + + /** + * List startup scripts + * @see https://www.vultr.com/api/#startupscript_startupscript_list + * @return mixed List of startup scripts + */ + public function startupscript_list() + { + return self::get('startupscript/list'); + } + + /** + * Update startup script + * @param int $script_id + * @param string $name + * @param string $script script contents + * @return int HTTP response code + * */ + public function startupscript_update($script_id, $name, $script) + { + $args = array( + 'SCRIPTID' => $script_id, + 'name' => $name, + 'script' => $script + ); + return self::code('startupscript/update', $args); + } + + /** + * Destroy startup script + * @see https://www.vultr.com/api/#startupscript_destroy + * @param int $script_id + * @return int HTTP respnose code + */ + public function startupscript_destroy($script_id) + { + $args = array('SCRIPTID' => $script_id); + return self::code('startupscript/destroy', $args); + } + + /** + * Create startup script + * @see https://www.vultr.com/api/#startupscript_create + * @param string $script_name + * @param string $script_contents + * @return int Script ID + */ + public function startupscript_create($script_name, $script_contents, $script_type) + { + $args = array( + 'name' => $script_name, + 'script' => $script_contents, + 'type' => $script_type + ); + $script = self::post('startupscript/create', $args); + return $script['SCRIPTID']; + } + + /** + * @param $region_id + * @param $plan_id + * @throws Exception + */ + public function server_available($region_id, $plan_id) + { + $availability = self::regions_availability($region_id); + if (!in_array($plan_id, $availability)) + { + throw new Exception('Plan ID ' . $plan_id . ' is not available in region ' . $region_id); + } + } + + /** + * List servers + * @see https://www.vultr.com/api/#server_server_list + * @return mixed List of servers + */ + public function server_list() + { + return self::get('server/list'); + } + + /** + * Display server bandwidth + * @see https://www.vultr.com/api/#server_bandwidth + * @param int $server_id + * @return mixed Bandwidth history + */ + public function bandwidth($server_id) + { + $args = array('SUBID' => (int)$server_id); + return self::get('server/bandwidth', $args); + } + + /** + * List IPv4 Addresses allocated to specified server + * @see https://www.vultr.com/api/#server_list_ipv4 + * @param int $server_id + * @return mixed IPv4 address list + */ + public function list_ipv4($server_id) + { + $args = array('SUBID' => (int)$server_id); + $ipv4 = self::get('server/list_ipv4', $args); + return $ipv4[(int)$server_id]; + } + + /** + * Create IPv4 address + * @see https://www.vultr.com/api/#server_create_ipv4 + * @param int $server_id + * @param string Reboot server after adding IP: , default: yes + * @return int HTTP response code + * */ + public function ipv4_create($server_id, $reboot = 'yes') + { + $args = array( + 'SUBID' => $server_id, + 'reboot' => ($reboot == 'yes' ? 'yes' : 'no') + ); + return self::code('server/create_ipv4', $args); + } + + /** + * Destroy IPv4 Address + * @see https://www.vultr.com/api/#server_destroy_ipv4 + * @param int $server_ID + * @param string $ip IPv4 address + * @return int HTTP response code + * */ + public function destroy_ipv4($server_id, $ip4) + { + $args = array( + 'SUBID' => $server_id, + 'ip' => $ip4 + ); + return self::code('server/destroy_ipv4', $args); + } + + /** + * Set Reverse DNS for IPv4 address + * @see https://www.vultr.com/api/#server_reverse_set_ipv4 + * @param string $ip + * @param string $rdns + * @return int HTTP response code + */ + public function reverse_set_ipv4($ip, $rdns, $id) + { + $args = array( + 'SUBID' => $id, + 'ip' => $ip, + 'entry' => $rdns + + ); + return self::code('server/reverse_set_ipv4', $args); + } + + /** + * Set Default Reverse DNS for IPv4 address + * @see https://www.vultr.com/api/#server_reverse_default_ipv4 + * @param string $server_id + * @param string $ip + * @return int HTTP response code + */ + public function reverse_default_ipv4($server_id, $ip) + { + $args = array( + 'SUBID' => (int)$server_id, + 'ip' => $ip + ); + return self::code('server/reverse_default_ipv4', $args); + } + + /** + * List IPv6 addresses for specified server + * @see https://www.vultr.com/api/#server_list_ipv6 + * @param int $server_id + * @return mixed IPv6 allocation info + */ + public function list_ipv6($server_id) + { + $args = array('SUBID' => (int)$server_id); + $ipv6 = self::get('server/list_ipv6', $args); + return $ipv6[(int)$server_id]; + } + + public function reverse_list_ipv6($server_id) + { + $args = array('SUBID' => (int)$server_id); + $ipv6 = self::get('server/reverse_list_ipv6', $args); + return $ipv6[(int)$server_id]; + } + + public function get_app_info($server_id) + { + $args = array('SUBID' => (int)$server_id); + $app_info = self::get('server/get_app_info', $args); + return $app_info['app_info']; + } + + + /** + * Set Reverse DNS for IPv6 address + * @see https://www.vultr.com/api/#server_reverse_set_ipv6 + * @param int $server_id + * @param string $ip + * @param string $rdns + * @return int HTTP response code + */ + public function reverse_set_ipv6($server_id, $ip, $rdns) + { + $args = array( + 'SUBID' => (int)$server_id, + 'ip' => $ip, + 'entry' => $rdns + ); + return self::code('server/reverse_set_ipv6', $args); + } + + /** + * Delete IPv6 Reverse DNS + * @see https://www.vultr.com/api/#server_reverse_delete_ipv6 + * @param int $server_id + * @param string $ip6 IPv6 address + * @return int HTTP response code + * */ + public function reverse_delete_ipv6($server_id, $ip6) + { + $args = array( + 'SUBID' => $server_id, + 'ip' => $ip6 + ); + return self::code('server/reverse_delete_ipv6', $args); + } + + /** + * Reboot server + * @see https://www.vultr.com/api/#server_reboot + * @param int $server_id + * @return int HTTP response code + */ + public function reboot($server_id) + { + $args = array('SUBID' => $server_id); + return self::code('server/reboot', $args); + } + + /** + * Halt server + * @see https://www.vultr.com/api/#server_halt + * @param int $server_id + * @return int HTTP response code + */ + public function halt($server_id) + { + $args = array('SUBID' => (int)$server_id); + return self::code('server/halt', $args); + } + + /** + * Start server + * @see https://www.vultr.com/api/#server_start + * @param int $server_id + * @return int HTTP response code + */ + public function start($server_id) + { + $args = array('SUBID' => (int)$server_id); + return self::code('server/start', $args); + } + + /** + * Destroy server + * @see https://www.vultr.com/api/#server_destroy + * @param int $server_id + * @return int HTTP response code + */ + public function destroy($server_id) + { + $args = array('SUBID' => (int)$server_id); + return self::code('server/destroy', $args); + } + + /** + * Reinstall OS on an instance + * @see https://www.vultr.com/api/#server_reinstall + * @param int $server_id + * @return int HTTP response code + */ + public function reinstall($server_id) + { + $args = array('SUBID' => (int)$server_id); + return self::code('server/reinstall', $args); + } + + /** + * Set server label + * @see https://www.vultr.com/api/#server_label_set + * @param int $server_id + * @param string $label + * @return int HTTP response code + */ + public function label_set($server_id, $label) + { + $args = array( + 'SUBID' => (int)$server_id, + 'label' => $label + ); + return self::code('server/label_set', $args); + } + + /** + * Restore Server Snapshot + * @see https://www.vultr.com/api/#server_restore_snapshot + * @param int $server_id + * @param string $snapshot_id Hexadecimal string with Restore ID + * @return int HTTP response code + */ + public function restore_snapshot($server_id, $snapshot_id) + { + $args = array( + 'SUBID' => (int)$server_id, + 'SNAPSHOTID' => preg_replace('/[^a-f0-9]/', '', $snapshot_id) + ); + return self::code('server/restore_snapshot', $args); + } + + /** + * Restore Backup + * @param int $server_id + * @param string $backup_id + * @return int HTTP response code + * */ + public function restore_backup($server_id, $backup_id) + { + $args = array( + 'SUBID' => $server_id, + 'BACKUPID' => $backup_id + ); + return self::code('server/restore_backup', $args); + } + + public function backup_list() + { + return self::get('backup/list'); + } + + /** + * @param $config + * @return bool|int|mixed|string + */ + public function create($config) + { + try + { + self::server_available((int)$config['DCID'], (int)$config['VPSPLANID']); + } + catch (Exception $e) + { + return FALSE; + } + + return self::post('server/create', $config); + } + + /** + * SSH Keys List method + * @see https://www.vultr.com/api/#sshkey_sshkey_list + * @return FALSE if no SSH keys are available + * @return mixed with whatever ssh keys get returned + */ + public function sshkeys_list() + { + $try = self::get('sshkey/list'); + if (sizeof($try) < 1) + { + return FALSE; + } + return $try; + } + + /** + * SSH Keys Create method + * @see https://www.vultr.com/api/#sshkey_sshkey_create + * @param string $name + * @param string $key [openssh formatted public key] + * @return FALSE if no SSH keys are available + * @return mixed with whatever ssh keys get returned + */ + public function sshkey_create($name, $key) + { + $args = array( + 'name' => $name, + 'ssh_key' => $key + ); + return self::post('sshkey/create', $args); + } + + /** + * SSH Keys Update method + * @see https://www.vultr.com/api/#sshkey_sshkey_update + * @param string $key_id + * @param string $name + * @param string $key [openssh formatted public key] + * @return int HTTP response code + */ + public function sshkey_update($key_id, $name, $key) + { + $args = array( + 'SSHKEYID' => $key_id, + 'name' => $name, + 'ssh_key' => $key + ); + return self::code('sshkey/update', $args); + } + + /** + * SSH Keys Destroy method + * @see https://www.vultr.com/api/#sshkey_sshkey_destroy + * @param string $key_id + * @return int HTTP response code + */ + public function sshkey_destroy($key_id) + { + $args = array('SSHKEYID' => $key_id); + return self::code('sshkey/destroy', $args); + } + + /** + * GET Method + * @param string $method + * @param mixed $args + */ + public function get($method, $args = FALSE) + { + $this->request_type = 'GET'; + $this->get_code = false; + return self::query($method, $args); + } + + /** + * CODE Method + * @param string $method + * @param mixed $args + * @return mixed if no exceptions thrown + * */ + public function code($method, $args = FALSE) + { + $this->request_type = 'POST'; + $this->get_code = true; + return self::query($method, $args); + } + + /** + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function post($method, $args) + { + $this->request_type = 'POST'; + return self::query($method, $args); + } + + /** + * API Query Function + * @param string $method + * @param mixed $args + */ + private function query($method, $args) + { + $methodArray = explode('/', $method); + $apiRequiredArray = array( + 'account', + 'auth', + 'backup', + 'baremetal', + 'block', + 'dns', + 'firewall', + 'iso', + 'network', + 'plans', + 'reservedip', + 'server', + 'snapshot', + 'sshkey', + 'startupscript', + 'user' + ); + + $url = $this->endpoint . $method; + $apiRequired = false; + + if ($this->debug) + { + echo $this->request_type . ' ' . $url . PHP_EOL; + } + + $_defaults = array( + CURLOPT_USERAGENT => sprintf('%s v%s (%s) - WHMCS Module', $this->agent, $this->version, 'https://github.com/usefulz/vultr-api-client'), + CURLOPT_HEADER => 0, + CURLOPT_VERBOSE => 0, + CURLOPT_SSL_VERIFYPEER => 0, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_HTTP_VERSION => '1.0', + CURLOPT_FOLLOWLOCATION => 0, + CURLOPT_FRESH_CONNECT => 1, + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_FORBID_REUSE => 1, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTPHEADER => array('Accept: application/json') + ); + + if (in_array($methodArray[0], $apiRequiredArray)) + { + array_push($_defaults[CURLOPT_HTTPHEADER], "API-Key: $this->api_token"); + $apiRequired = true; + } + + $cacheable = false; + switch ($this->request_type) + { + + case 'POST': + $post_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_POST] = 1; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'GET': + if ($args !== FALSE) + { + $get_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url . '?' . $get_data; + } + else + { + $_defaults[CURLOPT_URL] = $url; + } + + $cacheable = true; + $response = $this->serveFromCache($_defaults[CURLOPT_URL]); + if ($response !== false) + { + $this->response_code = 200; + return $response; + } + break; + + default: + break; + } + + // To avoid rate limit hits + if ($this->readLast() == time() && $apiRequired) + { + usleep(333, 334); + } + + $apisess = curl_init(); + curl_setopt_array($apisess, $_defaults); + $response = curl_exec($apisess); + $httpCode = curl_getinfo($apisess, CURLINFO_HTTP_CODE); + logModuleCall('Vultr', $url, $args, "HTTP Code: " . $httpCode . "\n" . $response); + $this->writeLast(); + + /** + * Check to see if there were any API exceptions thrown + * If so, then error out, otherwise, keep going. + */ + try + { + self::isAPIError($apisess, $response); + } + catch (Exception $e) + { + curl_close($apisess); + $message = $e->getMessage() . PHP_EOL; + $this->message = $message; + return $message; + } + + /** + * Close our session + * Return the decoded JSON response + */ + curl_close($apisess); + $obj = json_decode($response, true); + + if ($this->get_code) + { + return (int)$this->response_code; + } + + if ($cacheable) + { + $this->saveToCache($url, $response); + } + else + { + $this->purgeCache($url); + } + + return $obj; + } + + public function getCode() + { + return (int)$this->response_code; + } + + public function checkConnection() + { + return $this->getCode() == 200 ? true : false; + } + + public function getMessage() + { + return $this->message; + } + + /** + * API Error Handling + * @param cURL_Handle $response_obj + * @param string $response + * @throws Exception if invalid API location is provided + * @throws Exception if API token is missing from request + * @throws Exception if API method does not exist + * @throws Exception if Internal Server Error occurs + * @throws Exception if the request fails otherwise + */ + public function isAPIError($response_obj, $response) + { + + $code = curl_getinfo($response_obj, CURLINFO_HTTP_CODE); + $this->response_code = $code; + + if ($this->debug) + { + echo $code . PHP_EOL; + } + + switch ($code) + { + case 200: + break; + case 400: + throw new Exception('Invalid API location. Check the URL that you are using'); + break; + case 403: + throw new Exception('Invalid or missing API key. Check that your API key is present and matches your assigned key'); + break; + case 405: + throw new Exception('Invalid HTTP method. Check that the method (POST|GET) matches what the documentation indicates'); + break; + case 500: + throw new Exception('Internal server error. Try again at a later time'); + break; + case 412: + throw new Exception('Request failed: ' . $response); + break; + default: + break; + } + } + + protected function serveFromCache($url) + { + // garbage collect 5% of the time + if (mt_rand(0, 19) == 0) + { + $files = glob("$this->cache_dir/*"); + $old = time() - ($this->cache_ttl * 2); + foreach ($files as $file) + { + if (filemtime($file) < $old) + { + unlink($old); + } + } + } + + $hash = md5($url); + $group = $this->groupFromUrl($url); + $file = "$this->cache_dir/$group-$hash"; + if (file_exists($file) && filemtime($file) > (time() - $this->cache_ttl)) + { + $response = file_get_contents($file); + $obj = json_decode($response, true); + return $obj; + } + return false; + } + + protected function saveToCache($url, $json) + { + if (!file_exists($this->cache_dir)) + { + mkdir($this->cache_dir); + } + + $hash = md5($url); + $group = $this->groupFromUrl($url); + $file = "$this->cache_dir/$group-$hash"; + file_put_contents($file, $json); + } + + protected function groupFromUrl($url) + { + $group = 'default'; + if (preg_match('@/v1/([^/]+)/@', $url, $match)) + { + return $match[1]; + } + } + + protected function purgeCache($url) + { + $group = $this->groupFromUrl($url); + $files = glob("$this->cache_dir/$group-*"); + foreach ($files as $file) + { + unlink($file); + } + } + + protected function writeLast() + { + if (!file_exists($this->cache_dir)) + { + mkdir($this->cache_dir); + } + + file_put_contents("$this->cache_dir/last", time()); + } + + protected function readLast() + { + if (file_exists("$this->cache_dir/last")) + { + return file_get_contents("$this->cache_dir/last"); + } + } + } +} From 49ea7adbe0159e0375b62c311241149eafb38ab1 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Wed, 3 Feb 2021 19:41:27 -0500 Subject: [PATCH 06/23] Update VultrAPI2.php --- servers/vultr/vendor/VultrAPI2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/vultr/vendor/VultrAPI2.php b/servers/vultr/vendor/VultrAPI2.php index f017d26..931a2cf 100644 --- a/servers/vultr/vendor/VultrAPI2.php +++ b/servers/vultr/vendor/VultrAPI2.php @@ -179,7 +179,7 @@ public function os_change($subid, $osid) public function attach_iso($subid, $isoid) { - return self::code('server/iso_attach', array('SUBID' => $subid, 'ISOID' => $isoid)); + return self::code('instances/{instance-id}/iso/attach', array('SUBID' => $subid, 'ISOID' => $isoid)); } public function detach_iso($subid) @@ -864,7 +864,7 @@ private function query($method, $args) if (in_array($methodArray[0], $apiRequiredArray)) { - array_push($_defaults[CURLOPT_HTTPHEADER], "API-Key: $this->api_token"); + array_push($_defaults[CURLOPT_HTTPHEADER], "Authorization: Bearer $this->api_token"); $apiRequired = true; } From 68ed86dec7c020da7fab8bfd5a87c911e3372079 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Wed, 3 Feb 2021 21:41:56 -0500 Subject: [PATCH 07/23] Update VultrAPI2.php refactored most all of the api up to line 742 --- servers/vultr/vendor/VultrAPI2.php | 218 ++++++++++++++--------------- 1 file changed, 106 insertions(+), 112 deletions(-) diff --git a/servers/vultr/vendor/VultrAPI2.php b/servers/vultr/vendor/VultrAPI2.php index 931a2cf..a7c1f08 100644 --- a/servers/vultr/vendor/VultrAPI2.php +++ b/servers/vultr/vendor/VultrAPI2.php @@ -179,17 +179,17 @@ public function os_change($subid, $osid) public function attach_iso($subid, $isoid) { - return self::code('instances/{instance-id}/iso/attach', array('SUBID' => $subid, 'ISOID' => $isoid)); + return self::code('instances/{$subid}/iso/attach', array('iso_id' => $isoid)); } public function detach_iso($subid) { - return self::code('server/iso_detach', array('SUBID' => $subid)); + return self::code('instances/{$subid}/iso/detach'); } public function iso_status($subid) { - return self::get('server/iso_status', array('SUBID' => $subid)); + return self::get('instances/{$subid}/iso', array('SUBID' => $subid)); } /** @@ -199,7 +199,7 @@ public function iso_status($subid) */ public function snapshot_list() { - return self::get('snapshot/list'); + return self::get('snapshots'); } /** @@ -210,8 +210,8 @@ public function snapshot_list() */ public function snapshot_destroy($snapshot_id) { - $args = array('SNAPSHOTID' => $snapshot_id); - return self::code('snapshot/destroy', $args); + //$args = array('SNAPSHOTID' => $snapshot_id); + return self::code('snapshots/{$snapshot-id}'); } /** @@ -221,20 +221,20 @@ public function snapshot_destroy($snapshot_id) */ public function snapshot_create($server_id, $description) { - $args = array('SUBID' => $server_id, 'description' => $description); - return self::post('snapshot/create', $args); + $args = array('instance_id' => $server_id, 'description' => $description); + return self::post('snapshots', $args); } public function domain_create($domain, $serverIP) { - $args = array('domain' => $domain, 'serverip' => $serverIP); - return self::code('dns/create_domain', $args); + $args = array('domain' => $domain, 'ip' => $serverIP); + return self::code('domains', $args); } public function domain_delete($domain) { - $args = array('domain' => $domain); - return self::code('dns/delete_domain', $args); + //$args = array('domain' => $domain); + return self::code('domains/{$domain}'); } /** @@ -244,52 +244,52 @@ public function domain_delete($domain) * */ public function iso_list() { - return self::get('iso/list'); + return self::get('iso'); } public function dns_list() { - return self::get('dns/list'); + return self::get('domains'); } public function dns_records($domain) { - return self::get('dns/records', array('domain' => $domain)); + return self::get("domains/{$domain}/records"); } - public function create_record($args) + public function create_record($domain, $args) { - return self::code('dns/create_record', $args); + return self::code("domains/{$domain}/records", $args); } - public function delete_record($args) + public function delete_record($domain, $recordids) { - return self::code('dns/delete_record', $args); + return self::code("domains/{$domain}/records{$recordid}"); } - public function update_record($args) + public function update_record($domain, $args) { - return self::code('dns/update_record', $args); + return self::code("domains/{$domain}/records{$recordid}", $args); } - public function soa_update($args) + public function soa_update($domain, $args) { - return self::code('dns/soa_update', $args); + return self::code("domains/{$domain}/soa", $args); } - public function soa_info($args) + public function soa_info($domain, $args) { - return self::get('dns/soa_info', $args); + return self::get("domains/{$domain}/soa", $args); } public function upgrade_plan_list($subid) { - return self::get('server/upgrade_plan_list', array('SUBID' => $subid)); + return self::get("instances/{$subid}/upgrades" . '?type=plans'); } public function upgrade_plan($subid, $vpsplanid) { - return self::code('server/upgrade_plan', array('SUBID' => $subid, 'VPSPLANID' => $vpsplanid)); + return self::code("instances/{$subid}", array('plan' => $vpsplanid)); } /** @@ -299,17 +299,17 @@ public function upgrade_plan($subid, $vpsplanid) * */ public function app_list() { - return self::get('app/list'); + return self::get('applications'); } public function app_change_list($subid) { - return self::get('server/app_change_list', array('SUBID' => $subid)); + return self::get("instances/{$subid}/upgrades" . '?type=applications'); } public function app_change($subid, $appid) { - return self::code('server/app_change', array('SUBID' => $subid, 'APPID' => $appid)); + return self::code("instances/{$subid}", array('app_id' => $appid)); } /** @@ -319,7 +319,7 @@ public function app_change($subid, $appid) */ public function plans_list() { - return self::get('plans/list'); + return self::get('plans'); } /** @@ -329,7 +329,7 @@ public function plans_list() */ public function regions_list() { - return self::get('regions/list'); + return self::get('regions'); } /** @@ -341,13 +341,14 @@ public function regions_list() public function regions_availability($datacenter_id) { $did = (int)$datacenter_id; - return self::get('regions/availability?DCID=' . $did); + return self::get("regions/{$datacenter_id}/availability"); } + // https://www.vultr.com/api/#operation/get-instance-userdata public function server_userData($server_id) - { - return self::get('server/get_user_data', array('SUBID' => $server_id)); - } + { + return self::get("instances/{$server_id}/user-data"); + } /** * List startup scripts @@ -356,7 +357,7 @@ public function server_userData($server_id) */ public function startupscript_list() { - return self::get('startupscript/list'); + return self::get('startup-scripts'); } /** @@ -366,14 +367,14 @@ public function startupscript_list() * @param string $script script contents * @return int HTTP response code * */ - public function startupscript_update($script_id, $name, $script) + public function startupscript_update($script_id, $name, $script, $script_type='default') { $args = array( - 'SCRIPTID' => $script_id, + 'type' => $script_type, 'name' => $name, 'script' => $script ); - return self::code('startupscript/update', $args); + return self::code("startup-scripts/{$script_id}", $args); } /** @@ -384,8 +385,8 @@ public function startupscript_update($script_id, $name, $script) */ public function startupscript_destroy($script_id) { - $args = array('SCRIPTID' => $script_id); - return self::code('startupscript/destroy', $args); + //$args = array('SCRIPTID' => $script_id); + return self::code("startup-scripts/{$script_id}"); } /** @@ -402,7 +403,7 @@ public function startupscript_create($script_name, $script_contents, $script_typ 'script' => $script_contents, 'type' => $script_type ); - $script = self::post('startupscript/create', $args); + $script = self::post('startup-scripts', $args); return $script['SCRIPTID']; } @@ -427,37 +428,37 @@ public function server_available($region_id, $plan_id) */ public function server_list() { - return self::get('server/list'); + return self::get('instances'); } /** * Display server bandwidth - * @see https://www.vultr.com/api/#server_bandwidth + * @see https://www.vultr.com/api/#operation/get-instance-bandwidth * @param int $server_id * @return mixed Bandwidth history */ public function bandwidth($server_id) { - $args = array('SUBID' => (int)$server_id); - return self::get('server/bandwidth', $args); + //$args = array('SUBID' => (int)$server_id); + return self::get("instances/{$server_id}/bandwidth"); } /** * List IPv4 Addresses allocated to specified server - * @see https://www.vultr.com/api/#server_list_ipv4 + * @see https://www.vultr.com/api/#operation/get-instance-ipv4 * @param int $server_id * @return mixed IPv4 address list */ public function list_ipv4($server_id) { - $args = array('SUBID' => (int)$server_id); - $ipv4 = self::get('server/list_ipv4', $args); + //$args = array('SUBID' => (int)$server_id); + $ipv4 = self::get("instances/{$server_id}/ipv4"); return $ipv4[(int)$server_id]; } /** * Create IPv4 address - * @see https://www.vultr.com/api/#server_create_ipv4 + * @see https://www.vultr.com/api/#operation/create-instance-ipv4 * @param int $server_id * @param string Reboot server after adding IP: , default: yes * @return int HTTP response code @@ -465,31 +466,27 @@ public function list_ipv4($server_id) public function ipv4_create($server_id, $reboot = 'yes') { $args = array( - 'SUBID' => $server_id, 'reboot' => ($reboot == 'yes' ? 'yes' : 'no') ); - return self::code('server/create_ipv4', $args); + return self::code("instances/{$server_id}/ipv4", $args); } /** * Destroy IPv4 Address - * @see https://www.vultr.com/api/#server_destroy_ipv4 + * @see https://www.vultr.com/api/#operation/delete-instance-ipv4 * @param int $server_ID * @param string $ip IPv4 address * @return int HTTP response code * */ public function destroy_ipv4($server_id, $ip4) { - $args = array( - 'SUBID' => $server_id, - 'ip' => $ip4 - ); - return self::code('server/destroy_ipv4', $args); + + return self::code("instances/{$server_id}/ipv4/{$ip4}"); } /** * Set Reverse DNS for IPv4 address - * @see https://www.vultr.com/api/#server_reverse_set_ipv4 + * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv4 * @param string $ip * @param string $rdns * @return int HTTP response code @@ -497,17 +494,17 @@ public function destroy_ipv4($server_id, $ip4) public function reverse_set_ipv4($ip, $rdns, $id) { $args = array( - 'SUBID' => $id, + //'SUBID' => $id, 'ip' => $ip, - 'entry' => $rdns + 'reverse' => $rdns ); - return self::code('server/reverse_set_ipv4', $args); + return self::code("instances/{$id}/ipv4/reverse", $args); } /** * Set Default Reverse DNS for IPv4 address - * @see https://www.vultr.com/api/#server_reverse_default_ipv4 + * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv4 * @param string $server_id * @param string $ip * @return int HTTP response code @@ -515,29 +512,29 @@ public function reverse_set_ipv4($ip, $rdns, $id) public function reverse_default_ipv4($server_id, $ip) { $args = array( - 'SUBID' => (int)$server_id, + //'reverse' => (int)$server_id, 'ip' => $ip ); - return self::code('server/reverse_default_ipv4', $args); + return self::code("instances/{$server_id}/reverse/default", $args); } /** * List IPv6 addresses for specified server - * @see https://www.vultr.com/api/#server_list_ipv6 + * @see https://www.vultr.com/api/#operation/get-instance-ipv6 * @param int $server_id * @return mixed IPv6 allocation info */ public function list_ipv6($server_id) { - $args = array('SUBID' => (int)$server_id); - $ipv6 = self::get('server/list_ipv6', $args); + //$args = array('SUBID' => (int)$server_id); + $ipv6 = self::get("instances/{$server_id}/ipv6"); return $ipv6[(int)$server_id]; } public function reverse_list_ipv6($server_id) { - $args = array('SUBID' => (int)$server_id); - $ipv6 = self::get('server/reverse_list_ipv6', $args); + + $ipv6 = self::get("instances/{$server_id}/ipv6/reverse"); return $ipv6[(int)$server_id]; } @@ -551,7 +548,7 @@ public function get_app_info($server_id) /** * Set Reverse DNS for IPv6 address - * @see https://www.vultr.com/api/#server_reverse_set_ipv6 + * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv6 * @param int $server_id * @param string $ip * @param string $rdns @@ -560,92 +557,87 @@ public function get_app_info($server_id) public function reverse_set_ipv6($server_id, $ip, $rdns) { $args = array( - 'SUBID' => (int)$server_id, 'ip' => $ip, - 'entry' => $rdns + 'reverse' => $rdns ); - return self::code('server/reverse_set_ipv6', $args); + return self::code('instances/{$server_id}/ipv6/reverse', $args); } /** * Delete IPv6 Reverse DNS - * @see https://www.vultr.com/api/#server_reverse_delete_ipv6 + * @see https://www.vultr.com/api/#operation/delete-instance-reverse-ipv6 * @param int $server_id * @param string $ip6 IPv6 address * @return int HTTP response code * */ public function reverse_delete_ipv6($server_id, $ip6) { - $args = array( - 'SUBID' => $server_id, - 'ip' => $ip6 - ); - return self::code('server/reverse_delete_ipv6', $args); + + return self::code("instances/{$server_id}/ipv6/reverse/{$ip6}"); } /** * Reboot server - * @see https://www.vultr.com/api/#server_reboot + * @see https://www.vultr.com/api/#operation/reboot-instance * @param int $server_id * @return int HTTP response code */ public function reboot($server_id) { - $args = array('SUBID' => $server_id); - return self::code('server/reboot', $args); + return self::code("instances/{$server_id}/reboot"); } /** * Halt server - * @see https://www.vultr.com/api/#server_halt + * @see https://www.vultr.com/api/#operation/halt-instances * @param int $server_id * @return int HTTP response code */ public function halt($server_id) { - $args = array('SUBID' => (int)$server_id); - return self::code('server/halt', $args); + $args = array('instance_ids' => array((int)$server_id)); + return self::code('instances/halt', $args); } /** * Start server - * @see https://www.vultr.com/api/#server_start + * @see https://www.vultr.com/api/#operation/start-instances * @param int $server_id * @return int HTTP response code */ public function start($server_id) { - $args = array('SUBID' => (int)$server_id); - return self::code('server/start', $args); + $args = array('instance_ids' => array((int)$server_id)); + return self::code('instances/start', $args); } /** * Destroy server - * @see https://www.vultr.com/api/#server_destroy + * @see https://www.vultr.com/api/#operation/delete-instance * @param int $server_id * @return int HTTP response code */ public function destroy($server_id) { - $args = array('SUBID' => (int)$server_id); - return self::code('server/destroy', $args); + //$args = array('SUBID' => (int)$server_id); + return self::code("instances/{$server_id}", $args); } /** * Reinstall OS on an instance - * @see https://www.vultr.com/api/#server_reinstall + * @see https://www.vultr.com/api/#operation/reinstall-instance * @param int $server_id * @return int HTTP response code */ - public function reinstall($server_id) + public function reinstall($server_id, $hostname='') { - $args = array('SUBID' => (int)$server_id); - return self::code('server/reinstall', $args); + $args = array('hostname' => $hostname); + return self::code("instances/{$server_id}/reinstall", $args); } /** * Set server label - * @see https://www.vultr.com/api/#server_label_set + * @see https://www.vultr.com/api/#operation/update-instance * @param int $server_id * @param string $label * @return int HTTP response code @@ -653,15 +645,15 @@ public function reinstall($server_id) public function label_set($server_id, $label) { $args = array( - 'SUBID' => (int)$server_id, + //'SUBID' => (int)$server_id, 'label' => $label ); - return self::code('server/label_set', $args); + return self::code("instances/{$server_id}", $args); } /** * Restore Server Snapshot - * @see https://www.vultr.com/api/#server_restore_snapshot + * @see https://www.vultr.com/api/#operation/restore-instance * @param int $server_id * @param string $snapshot_id Hexadecimal string with Restore ID * @return int HTTP response code @@ -669,10 +661,10 @@ public function label_set($server_id, $label) public function restore_snapshot($server_id, $snapshot_id) { $args = array( - 'SUBID' => (int)$server_id, - 'SNAPSHOTID' => preg_replace('/[^a-f0-9]/', '', $snapshot_id) + //'backup_id' => (int)$server_id, + 'snapshot_id' => preg_replace('/[^a-f0-9]/', '', $snapshot_id) ); - return self::code('server/restore_snapshot', $args); + return self::code("instances/{$server_id}/restore", $args); } /** @@ -684,18 +676,20 @@ public function restore_snapshot($server_id, $snapshot_id) public function restore_backup($server_id, $backup_id) { $args = array( - 'SUBID' => $server_id, - 'BACKUPID' => $backup_id + //'SUBID' => $server_id, + 'backup_id' => $backup_id ); - return self::code('server/restore_backup', $args); + return self::code("instances/{$server_id}/restore", $args); } public function backup_list() { - return self::get('backup/list'); + return self::get('backups'); } /** + * Server Create + * @see https://www.vultr.com/api/#operation/create-instance * @param $config * @return bool|int|mixed|string */ @@ -710,7 +704,7 @@ public function create($config) return FALSE; } - return self::post('server/create', $config); + return self::post('instances', $config); } /** @@ -721,7 +715,7 @@ public function create($config) */ public function sshkeys_list() { - $try = self::get('sshkey/list'); + $try = self::get('ssh-keys'); if (sizeof($try) < 1) { return FALSE; @@ -743,9 +737,9 @@ public function sshkey_create($name, $key) 'name' => $name, 'ssh_key' => $key ); - return self::post('sshkey/create', $args); + return self::post('ssh-keys', $args); } - + // leftoff /** * SSH Keys Update method * @see https://www.vultr.com/api/#sshkey_sshkey_update From a17f7a84a8bfc0eb7fdae505e3d7727bfeb03c2a Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Thu, 4 Feb 2021 18:34:07 -0500 Subject: [PATCH 08/23] Update VultrAPI2.php More refactoring work done --- servers/vultr/vendor/VultrAPI2.php | 331 +++++++++++++++++++++-------- 1 file changed, 247 insertions(+), 84 deletions(-) diff --git a/servers/vultr/vendor/VultrAPI2.php b/servers/vultr/vendor/VultrAPI2.php index a7c1f08..24f5d05 100644 --- a/servers/vultr/vendor/VultrAPI2.php +++ b/servers/vultr/vendor/VultrAPI2.php @@ -1,15 +1,15 @@ $subid)); + return self::get("instances/{$subid}/upgrades?type=os"); } - // needs done + + /** + * OS Change/ Reinstall + * @see https://www.vultr.com/api/#operation/update-instance + * @see + * @param mixed $subid + * @param mixed $osid // https://www.vultr.com/api/#operation/list-isos + * @return mixed + */ public function os_change($subid, $osid) { - return self::code('server/os_change', array('SUBID' => $subid, 'OSID' => $osid)); + return self::patch("instances/{$subid}", array('os_id' => $osid)); } - + + /** + * List available ISO iamges + * @see https://www.vultr.com/api/#iso_list + * @return mixed Available ISO images + * */ + public function iso_list() + { + return self::get('iso'); + } + + /** + * Attach ISO + * @see https://www.vultr.com/api/#operation/attach-instance-iso + * @param mixed $subid + * @param mixed $isoid + * @return mixed + */ public function attach_iso($subid, $isoid) { - return self::code('instances/{$subid}/iso/attach', array('iso_id' => $isoid)); + return self::post("instances/{$subid}/iso/attach", array('iso_id' => $isoid)); } - + + /** + * Detach ISO + * @see https://www.vultr.com/api/#operation/detach-instance-iso + * @param mixed $subid + * @return mixed + */ public function detach_iso($subid) { - return self::code('instances/{$subid}/iso/detach'); + return self::post("instances/{$subid}/iso/detach"); } - + + /** + * Get ISO Status + * @see https://www.vultr.com/api/#operation/get-instance-iso-status + * @param [type] $subid + * @return mixed + */ public function iso_status($subid) { - return self::get('instances/{$subid}/iso', array('SUBID' => $subid)); + return self::get("instances/{$subid}/iso"); } /** @@ -211,7 +255,7 @@ public function snapshot_list() public function snapshot_destroy($snapshot_id) { //$args = array('SNAPSHOTID' => $snapshot_id); - return self::code('snapshots/{$snapshot-id}'); + return self::delete("snapshots/{$snapshot_id}"); } /** @@ -224,28 +268,31 @@ public function snapshot_create($server_id, $description) $args = array('instance_id' => $server_id, 'description' => $description); return self::post('snapshots', $args); } - + + /** + * Create Domain + * @see https://www.vultr.com/api/#operation/create-dns-domain + * @param string $domain + * @param string $serverIP // optional IP for the Domain DNS + */ public function domain_create($domain, $serverIP) { $args = array('domain' => $domain, 'ip' => $serverIP); - return self::code('domains', $args); + return self::post('domains', $args); } - + + /** + * Delete Domain + * @see https://www.vultr.com/api/#operation/delete-dns-domain-record + * @param string $domain + */ public function domain_delete($domain) { //$args = array('domain' => $domain); - return self::code('domains/{$domain}'); + return self::delete("domains/{$domain}"); } - /** - * List available ISO iamges - * @see https://www.vultr.com/api/#iso_list - * @return mixed Available ISO images - * */ - public function iso_list() - { - return self::get('iso'); - } + public function dns_list() { @@ -259,22 +306,22 @@ public function dns_records($domain) public function create_record($domain, $args) { - return self::code("domains/{$domain}/records", $args); + return self::post("domains/{$domain}/records", $args); } public function delete_record($domain, $recordids) { - return self::code("domains/{$domain}/records{$recordid}"); + return self::delete("domains/{$domain}/records{$recordid}"); } public function update_record($domain, $args) { - return self::code("domains/{$domain}/records{$recordid}", $args); + return self::patch("domains/{$domain}/records{$recordid}", $args); } public function soa_update($domain, $args) { - return self::code("domains/{$domain}/soa", $args); + return self::patch("domains/{$domain}/soa", $args); } public function soa_info($domain, $args) @@ -286,10 +333,17 @@ public function upgrade_plan_list($subid) { return self::get("instances/{$subid}/upgrades" . '?type=plans'); } - + + /** + * Upgrade Plan + * @see https://www.vultr.com/api/#operation/update-instance + * @param string $subid + * @param integer $vpsplanid // https://www.vultr.com/api/#operation/list-plans + * @return void + */ public function upgrade_plan($subid, $vpsplanid) { - return self::code("instances/{$subid}", array('plan' => $vpsplanid)); + return self::patch("instances/{$subid}", array('plan' => $vpsplanid)); } /** @@ -301,15 +355,26 @@ public function app_list() { return self::get('applications'); } - + + /** + * List available applications for instance + * @see https://www.vultr.com/api/#operation/get-instance-upgrades + * @return mixed Available applications + */ public function app_change_list($subid) { - return self::get("instances/{$subid}/upgrades" . '?type=applications'); + return self::get("instances/{$subid}/upgrades?type=applications"); } - + + /** + * Reinstall via Application ID + * @see https://www.vultr.com/api/#operation/update-instance + * @param integer $subid // server + * @param integer $appid // Available applications from https://www.vultr.com/api/#operation/list-applications + */ public function app_change($subid, $appid) { - return self::code("instances/{$subid}", array('app_id' => $appid)); + return self::patch("instances/{$subid}", array('app_id' => $appid)); } /** @@ -362,6 +427,7 @@ public function startupscript_list() /** * Update startup script + * @see https://www.vultr.com/api/#operation/update-startup-script * @param int $script_id * @param string $name * @param string $script script contents @@ -374,7 +440,7 @@ public function startupscript_update($script_id, $name, $script, $script_type='d 'name' => $name, 'script' => $script ); - return self::code("startup-scripts/{$script_id}", $args); + return self::patch("startup-scripts/{$script_id}", $args); } /** @@ -386,12 +452,12 @@ public function startupscript_update($script_id, $name, $script, $script_type='d public function startupscript_destroy($script_id) { //$args = array('SCRIPTID' => $script_id); - return self::code("startup-scripts/{$script_id}"); + return self::delete("startup-scripts/{$script_id}"); } /** * Create startup script - * @see https://www.vultr.com/api/#startupscript_create + * @see https://www.vultr.com/api/#operation/create-startup-script * @param string $script_name * @param string $script_contents * @return int Script ID @@ -404,7 +470,7 @@ public function startupscript_create($script_name, $script_contents, $script_typ 'type' => $script_type ); $script = self::post('startup-scripts', $args); - return $script['SCRIPTID']; + return $script['startup_script']['id']; } /** @@ -468,7 +534,7 @@ public function ipv4_create($server_id, $reboot = 'yes') $args = array( 'reboot' => ($reboot == 'yes' ? 'yes' : 'no') ); - return self::code("instances/{$server_id}/ipv4", $args); + return self::post("instances/{$server_id}/ipv4", $args); } /** @@ -481,7 +547,7 @@ public function ipv4_create($server_id, $reboot = 'yes') public function destroy_ipv4($server_id, $ip4) { - return self::code("instances/{$server_id}/ipv4/{$ip4}"); + return self::delete("instances/{$server_id}/ipv4/{$ip4}"); } /** @@ -499,12 +565,12 @@ public function reverse_set_ipv4($ip, $rdns, $id) 'reverse' => $rdns ); - return self::code("instances/{$id}/ipv4/reverse", $args); + return self::post("instances/{$id}/ipv4/reverse", $args); } /** * Set Default Reverse DNS for IPv4 address - * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv4 + * @see https://www.vultr.com/api/#operation/post-instances-instance-id-ipv4-reverse-default * @param string $server_id * @param string $ip * @return int HTTP response code @@ -515,7 +581,7 @@ public function reverse_default_ipv4($server_id, $ip) //'reverse' => (int)$server_id, 'ip' => $ip ); - return self::code("instances/{$server_id}/reverse/default", $args); + return self::post("instances/{$server_id}/reverse/default", $args); } /** @@ -530,19 +596,32 @@ public function list_ipv6($server_id) $ipv6 = self::get("instances/{$server_id}/ipv6"); return $ipv6[(int)$server_id]; } - + + /** + * List Instance IPv6 Reverse + * @see https://www.vultr.com/api/#operation/list-instance-ipv6-reverse + * @param int $server_id + * @return mixed IPv6 allocation info + */ public function reverse_list_ipv6($server_id) { $ipv6 = self::get("instances/{$server_id}/ipv6/reverse"); return $ipv6[(int)$server_id]; } - + + /** + * Get Application Information + * @see https://www.vultr.com/api/#operation/get-instance + * @param int $server_id + * @return mixed Application Information + */ public function get_app_info($server_id) { - $args = array('SUBID' => (int)$server_id); - $app_info = self::get('server/get_app_info', $args); - return $app_info['app_info']; + //$args = array('SUBID' => (int)$server_id); + $app_id = self::get("instances/{$server_id}")['app_id']; + $app_info = self::get("instances/{$server_id}")['applications'][$app_id]; + return $app_info['name']; } @@ -560,7 +639,7 @@ public function reverse_set_ipv6($server_id, $ip, $rdns) 'ip' => $ip, 'reverse' => $rdns ); - return self::code('instances/{$server_id}/ipv6/reverse', $args); + return self::post('instances/{$server_id}/ipv6/reverse', $args); } /** @@ -573,7 +652,7 @@ public function reverse_set_ipv6($server_id, $ip, $rdns) public function reverse_delete_ipv6($server_id, $ip6) { - return self::code("instances/{$server_id}/ipv6/reverse/{$ip6}"); + return self::delete("instances/{$server_id}/ipv6/reverse/{$ip6}"); } /** @@ -584,7 +663,7 @@ public function reverse_delete_ipv6($server_id, $ip6) */ public function reboot($server_id) { - return self::code("instances/{$server_id}/reboot"); + return self::post("instances/{$server_id}/reboot"); } /** @@ -596,19 +675,18 @@ public function reboot($server_id) public function halt($server_id) { $args = array('instance_ids' => array((int)$server_id)); - return self::code('instances/halt', $args); + return self::post('instances/halt', $args); } /** * Start server - * @see https://www.vultr.com/api/#operation/start-instances + * @see https://www.vultr.com/api/#operation/start-instance * @param int $server_id * @return int HTTP response code */ public function start($server_id) { - $args = array('instance_ids' => array((int)$server_id)); - return self::code('instances/start', $args); + return self::post("instances/{$server_id}/start"); } /** @@ -620,7 +698,7 @@ public function start($server_id) public function destroy($server_id) { //$args = array('SUBID' => (int)$server_id); - return self::code("instances/{$server_id}", $args); + return self::delete("instances/{$server_id}"); } /** @@ -632,7 +710,7 @@ public function destroy($server_id) public function reinstall($server_id, $hostname='') { $args = array('hostname' => $hostname); - return self::code("instances/{$server_id}/reinstall", $args); + return self::post("instances/{$server_id}/reinstall", $args); } /** @@ -648,7 +726,7 @@ public function label_set($server_id, $label) //'SUBID' => (int)$server_id, 'label' => $label ); - return self::code("instances/{$server_id}", $args); + return self::patch("instances/{$server_id}", $args); } /** @@ -664,24 +742,30 @@ public function restore_snapshot($server_id, $snapshot_id) //'backup_id' => (int)$server_id, 'snapshot_id' => preg_replace('/[^a-f0-9]/', '', $snapshot_id) ); - return self::code("instances/{$server_id}/restore", $args); + return self::post("instances/{$server_id}/restore", $args); } /** * Restore Backup + * @see https://www.vultr.com/api/#operation/restore-instance * @param int $server_id * @param string $backup_id * @return int HTTP response code - * */ + */ public function restore_backup($server_id, $backup_id) { $args = array( //'SUBID' => $server_id, 'backup_id' => $backup_id ); - return self::code("instances/{$server_id}/restore", $args); + return self::post("instances/{$server_id}/restore", $args); } - + + /** + * List Backups + * @see https://www.vultr.com/api/#operation/list-backups + * @return mixed + */ public function backup_list() { return self::get('backups'); @@ -739,7 +823,7 @@ public function sshkey_create($name, $key) ); return self::post('ssh-keys', $args); } - // leftoff + /** * SSH Keys Update method * @see https://www.vultr.com/api/#sshkey_sshkey_update @@ -755,7 +839,7 @@ public function sshkey_update($key_id, $name, $key) 'name' => $name, 'ssh_key' => $key ); - return self::code('sshkey/update', $args); + return self::patch('sshkey/update', $args); } /** @@ -767,7 +851,7 @@ public function sshkey_update($key_id, $name, $key) public function sshkey_destroy($key_id) { $args = array('SSHKEYID' => $key_id); - return self::code('sshkey/destroy', $args); + return self::delete('sshkey/destroy', $args); } /** @@ -782,20 +866,47 @@ public function get($method, $args = FALSE) return self::query($method, $args); } + /** - * CODE Method - * @param string $method - * @param mixed $args - * @return mixed if no exceptions thrown - * */ - public function code($method, $args = FALSE) + * DELETE Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function delete($method, $args) { - $this->request_type = 'POST'; - $this->get_code = true; + $this->request_type = 'DELETE'; + return self::query($method, $args); + } + + + // /** + // * CODE Method + // * @param string $method + // * @param mixed $args + // * @return mixed if no exceptions thrown + // * */ + // public function code($method, $args = FALSE) + // { + // $this->request_type = 'POST'; + // $this->get_code = true; + // return self::query($method, $args); + // } + + /** + * PATCH Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function patch($method, $args) + { + $this->request_type = 'PATCH'; return self::query($method, $args); } /** + * POST Method * @param $method * @param $args * @return bool|int|mixed|string @@ -805,6 +916,18 @@ public function post($method, $args) $this->request_type = 'POST'; return self::query($method, $args); } + + /** + * PUT Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function put($method, $args) + { + $this->request_type = 'PUT'; + return self::query($method, $args); + } /** * API Query Function @@ -830,7 +953,14 @@ private function query($method, $args) 'snapshot', 'sshkey', 'startupscript', - 'user' + 'user', + 'type', + 'per_page', + 'instance_id', + 'tag', + 'label', + 'main_ip', + 'cursor' ); $url = $this->endpoint . $method; @@ -842,7 +972,7 @@ private function query($method, $args) } $_defaults = array( - CURLOPT_USERAGENT => sprintf('%s v%s (%s) - WHMCS Module', $this->agent, $this->version, 'https://github.com/usefulz/vultr-api-client'), + CURLOPT_USERAGENT => sprintf('%s v%s (%s) - WHMCS Module', $this->agent, $this->version, 'https://github.com/whattheserver/whmcs-vultr'), CURLOPT_HEADER => 0, CURLOPT_VERBOSE => 0, CURLOPT_SSL_VERIFYPEER => 0, @@ -872,6 +1002,27 @@ private function query($method, $args) $_defaults[CURLOPT_POST] = 1; $_defaults[CURLOPT_POSTFIELDS] = $post_data; break; + + case 'PUT': + $post_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'PUT'; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'PATCH': + $post_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'PATCH'; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'DELETE': + //$post_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'DELETE'; + //$_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; case 'GET': if ($args !== FALSE) @@ -990,17 +1141,29 @@ public function isAPIError($response_obj, $response) { case 200: break; + case 201: + break; + case 202: + break; + case 204: + break; case 400: - throw new Exception('Invalid API location. Check the URL that you are using'); + throw new Exception('400: Bad Request'); + break; + case 401: + throw new Exception('401: Unauthorized'); break; case 403: - throw new Exception('Invalid or missing API key. Check that your API key is present and matches your assigned key'); + throw new Exception('403: Forbidden'); break; - case 405: - throw new Exception('Invalid HTTP method. Check that the method (POST|GET) matches what the documentation indicates'); + case 404: + throw new Exception('404: Not Found'); break; case 500: - throw new Exception('Internal server error. Try again at a later time'); + throw new Exception('500: Internal Server Error'); + break; + case 503: + throw new Exception('503: Service Unavailable. Your request exceeded the API rate limit.'); break; case 412: throw new Exception('Request failed: ' . $response); From 55a535a62b119d7407b9ee3085e59cc9645f4153 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 04:03:55 -0400 Subject: [PATCH 09/23] Update VultrAPI2.php Tested and corrected alot of functions based on testing the API. Refactored app_list and some others to match the old format response wise with hopes this will make things work smoothly when transitioning to V2 API as the data should be more like the old expected format.and require less refactoring. --- servers/vultr/vendor/VultrAPI2.php | 2571 ++++++++++++++-------------- 1 file changed, 1319 insertions(+), 1252 deletions(-) diff --git a/servers/vultr/vendor/VultrAPI2.php b/servers/vultr/vendor/VultrAPI2.php index 24f5d05..160b413 100644 --- a/servers/vultr/vendor/VultrAPI2.php +++ b/servers/vultr/vendor/VultrAPI2.php @@ -1,1254 +1,1321 @@ api_token = $token; - $this->cache_ttl = $cache_ttl; - $this->account = self::account_info(); - } - - /** - * Get Account info - * @see https://www.vultr.com/api/#tag/account - * @return mixed - */ - public function account_info() - { - return self::get('account'); - } - - /** - * Get OS list - * @see https://www.vultr.com/api/#operation/list-os - * @return mixed - */ - public function os_list() - { - return self::get('os'); - } - - /** - * OS Upgrade/Change Options - * @see https://www.vultr.com/api/#operation/get-instance-upgrades - * @see - * @param mixed $subid - * @return mixed - */ - public function os_change_list($subid) - { - return self::get("instances/{$subid}/upgrades?type=os"); - } - - /** - * OS Change/ Reinstall - * @see https://www.vultr.com/api/#operation/update-instance - * @see - * @param mixed $subid - * @param mixed $osid // https://www.vultr.com/api/#operation/list-isos - * @return mixed - */ - public function os_change($subid, $osid) - { - return self::patch("instances/{$subid}", array('os_id' => $osid)); - } - - /** - * List available ISO iamges - * @see https://www.vultr.com/api/#iso_list - * @return mixed Available ISO images - * */ - public function iso_list() - { - return self::get('iso'); - } - - /** - * Attach ISO - * @see https://www.vultr.com/api/#operation/attach-instance-iso - * @param mixed $subid - * @param mixed $isoid - * @return mixed - */ - public function attach_iso($subid, $isoid) - { - return self::post("instances/{$subid}/iso/attach", array('iso_id' => $isoid)); - } - - /** - * Detach ISO - * @see https://www.vultr.com/api/#operation/detach-instance-iso - * @param mixed $subid - * @return mixed - */ - public function detach_iso($subid) - { - return self::post("instances/{$subid}/iso/detach"); - } - - /** - * Get ISO Status - * @see https://www.vultr.com/api/#operation/get-instance-iso-status - * @param [type] $subid - * @return mixed - */ - public function iso_status($subid) - { - return self::get("instances/{$subid}/iso"); - } - - /** - * List available snapshots - * @see https://www.vultr.com/api/#snapshot_snapshot_list - * @return mixed - */ - public function snapshot_list() - { - return self::get('snapshots'); - } - - /** - * Destroy snapshot - * @see https://www.vultr.com/api/#snapshot_destroy - * @param int $snapshot_id - * @return int HTTP response code - */ - public function snapshot_destroy($snapshot_id) - { - //$args = array('SNAPSHOTID' => $snapshot_id); - return self::delete("snapshots/{$snapshot_id}"); - } - - /** - * Create snapshot - * @see https://www.vultr.com/api/#snapshot_create - * @param int $server_id - */ - public function snapshot_create($server_id, $description) - { - $args = array('instance_id' => $server_id, 'description' => $description); - return self::post('snapshots', $args); - } - - /** - * Create Domain - * @see https://www.vultr.com/api/#operation/create-dns-domain - * @param string $domain - * @param string $serverIP // optional IP for the Domain DNS - */ - public function domain_create($domain, $serverIP) - { - $args = array('domain' => $domain, 'ip' => $serverIP); - return self::post('domains', $args); - } - - /** - * Delete Domain - * @see https://www.vultr.com/api/#operation/delete-dns-domain-record - * @param string $domain - */ - public function domain_delete($domain) - { - //$args = array('domain' => $domain); - return self::delete("domains/{$domain}"); - } - - - - public function dns_list() - { - return self::get('domains'); - } - - public function dns_records($domain) - { - return self::get("domains/{$domain}/records"); - } - - public function create_record($domain, $args) - { - return self::post("domains/{$domain}/records", $args); - } - - public function delete_record($domain, $recordids) - { - return self::delete("domains/{$domain}/records{$recordid}"); - } - - public function update_record($domain, $args) - { - return self::patch("domains/{$domain}/records{$recordid}", $args); - } - - public function soa_update($domain, $args) - { - return self::patch("domains/{$domain}/soa", $args); - } - - public function soa_info($domain, $args) - { - return self::get("domains/{$domain}/soa", $args); - } - - public function upgrade_plan_list($subid) - { - return self::get("instances/{$subid}/upgrades" . '?type=plans'); - } - - /** - * Upgrade Plan - * @see https://www.vultr.com/api/#operation/update-instance - * @param string $subid - * @param integer $vpsplanid // https://www.vultr.com/api/#operation/list-plans - * @return void - */ - public function upgrade_plan($subid, $vpsplanid) - { - return self::patch("instances/{$subid}", array('plan' => $vpsplanid)); - } - - /** - * List available applications - * @see https://www.vultr.com/api/#app_app_list - * @return mixed Available applications - * */ - public function app_list() - { - return self::get('applications'); - } - - /** - * List available applications for instance - * @see https://www.vultr.com/api/#operation/get-instance-upgrades - * @return mixed Available applications - */ - public function app_change_list($subid) - { - return self::get("instances/{$subid}/upgrades?type=applications"); - } - - /** - * Reinstall via Application ID - * @see https://www.vultr.com/api/#operation/update-instance - * @param integer $subid // server - * @param integer $appid // Available applications from https://www.vultr.com/api/#operation/list-applications - */ - public function app_change($subid, $appid) - { - return self::patch("instances/{$subid}", array('app_id' => $appid)); - } - - /** - * List available plans - * @see https://www.vultr.com/api/#plans_plan_list - * @return mixed - */ - public function plans_list() - { - return self::get('plans'); - } - - /** - * List available regions - * @see https://www.vultr.com/api/#regions_region_list - * @return mixed - */ - public function regions_list() - { - return self::get('regions'); - } - - /** - * Determine region availability - * @see https://www.vultr.com/api/#regions_region_available - * @param int $datacenter_id - * @return mixed VPS plans available at given region - */ - public function regions_availability($datacenter_id) - { - $did = (int)$datacenter_id; - return self::get("regions/{$datacenter_id}/availability"); - } - - // https://www.vultr.com/api/#operation/get-instance-userdata - public function server_userData($server_id) - { - return self::get("instances/{$server_id}/user-data"); - } - - /** - * List startup scripts - * @see https://www.vultr.com/api/#startupscript_startupscript_list - * @return mixed List of startup scripts - */ - public function startupscript_list() - { - return self::get('startup-scripts'); - } - - /** - * Update startup script - * @see https://www.vultr.com/api/#operation/update-startup-script - * @param int $script_id - * @param string $name - * @param string $script script contents - * @return int HTTP response code - * */ - public function startupscript_update($script_id, $name, $script, $script_type='default') - { - $args = array( - 'type' => $script_type, - 'name' => $name, - 'script' => $script - ); - return self::patch("startup-scripts/{$script_id}", $args); - } - - /** - * Destroy startup script - * @see https://www.vultr.com/api/#startupscript_destroy - * @param int $script_id - * @return int HTTP respnose code - */ - public function startupscript_destroy($script_id) - { - //$args = array('SCRIPTID' => $script_id); - return self::delete("startup-scripts/{$script_id}"); - } - - /** - * Create startup script - * @see https://www.vultr.com/api/#operation/create-startup-script - * @param string $script_name - * @param string $script_contents - * @return int Script ID - */ - public function startupscript_create($script_name, $script_contents, $script_type) - { - $args = array( - 'name' => $script_name, - 'script' => $script_contents, - 'type' => $script_type - ); - $script = self::post('startup-scripts', $args); - return $script['startup_script']['id']; - } - - /** - * @param $region_id - * @param $plan_id - * @throws Exception - */ - public function server_available($region_id, $plan_id) - { - $availability = self::regions_availability($region_id); - if (!in_array($plan_id, $availability)) - { - throw new Exception('Plan ID ' . $plan_id . ' is not available in region ' . $region_id); - } - } - - /** - * List servers - * @see https://www.vultr.com/api/#server_server_list - * @return mixed List of servers - */ - public function server_list() - { - return self::get('instances'); - } - - /** - * Display server bandwidth - * @see https://www.vultr.com/api/#operation/get-instance-bandwidth - * @param int $server_id - * @return mixed Bandwidth history - */ - public function bandwidth($server_id) - { - //$args = array('SUBID' => (int)$server_id); - return self::get("instances/{$server_id}/bandwidth"); - } - - /** - * List IPv4 Addresses allocated to specified server - * @see https://www.vultr.com/api/#operation/get-instance-ipv4 - * @param int $server_id - * @return mixed IPv4 address list - */ - public function list_ipv4($server_id) - { - //$args = array('SUBID' => (int)$server_id); - $ipv4 = self::get("instances/{$server_id}/ipv4"); - return $ipv4[(int)$server_id]; - } - - /** - * Create IPv4 address - * @see https://www.vultr.com/api/#operation/create-instance-ipv4 - * @param int $server_id - * @param string Reboot server after adding IP: , default: yes - * @return int HTTP response code - * */ - public function ipv4_create($server_id, $reboot = 'yes') - { - $args = array( - 'reboot' => ($reboot == 'yes' ? 'yes' : 'no') - ); - return self::post("instances/{$server_id}/ipv4", $args); - } - - /** - * Destroy IPv4 Address - * @see https://www.vultr.com/api/#operation/delete-instance-ipv4 - * @param int $server_ID - * @param string $ip IPv4 address - * @return int HTTP response code - * */ - public function destroy_ipv4($server_id, $ip4) - { - - return self::delete("instances/{$server_id}/ipv4/{$ip4}"); - } - - /** - * Set Reverse DNS for IPv4 address - * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv4 - * @param string $ip - * @param string $rdns - * @return int HTTP response code - */ - public function reverse_set_ipv4($ip, $rdns, $id) - { - $args = array( - //'SUBID' => $id, - 'ip' => $ip, - 'reverse' => $rdns - - ); - return self::post("instances/{$id}/ipv4/reverse", $args); - } - - /** - * Set Default Reverse DNS for IPv4 address - * @see https://www.vultr.com/api/#operation/post-instances-instance-id-ipv4-reverse-default - * @param string $server_id - * @param string $ip - * @return int HTTP response code - */ - public function reverse_default_ipv4($server_id, $ip) - { - $args = array( - //'reverse' => (int)$server_id, - 'ip' => $ip - ); - return self::post("instances/{$server_id}/reverse/default", $args); - } - - /** - * List IPv6 addresses for specified server - * @see https://www.vultr.com/api/#operation/get-instance-ipv6 - * @param int $server_id - * @return mixed IPv6 allocation info - */ - public function list_ipv6($server_id) - { - //$args = array('SUBID' => (int)$server_id); - $ipv6 = self::get("instances/{$server_id}/ipv6"); - return $ipv6[(int)$server_id]; - } - - /** - * List Instance IPv6 Reverse - * @see https://www.vultr.com/api/#operation/list-instance-ipv6-reverse - * @param int $server_id - * @return mixed IPv6 allocation info - */ - public function reverse_list_ipv6($server_id) - { - - $ipv6 = self::get("instances/{$server_id}/ipv6/reverse"); - return $ipv6[(int)$server_id]; - } - - /** - * Get Application Information - * @see https://www.vultr.com/api/#operation/get-instance - * @param int $server_id - * @return mixed Application Information - */ - public function get_app_info($server_id) - { - //$args = array('SUBID' => (int)$server_id); - $app_id = self::get("instances/{$server_id}")['app_id']; - $app_info = self::get("instances/{$server_id}")['applications'][$app_id]; - return $app_info['name']; - } - - - /** - * Set Reverse DNS for IPv6 address - * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv6 - * @param int $server_id - * @param string $ip - * @param string $rdns - * @return int HTTP response code - */ - public function reverse_set_ipv6($server_id, $ip, $rdns) - { - $args = array( - 'ip' => $ip, - 'reverse' => $rdns - ); - return self::post('instances/{$server_id}/ipv6/reverse', $args); - } - - /** - * Delete IPv6 Reverse DNS - * @see https://www.vultr.com/api/#operation/delete-instance-reverse-ipv6 - * @param int $server_id - * @param string $ip6 IPv6 address - * @return int HTTP response code - * */ - public function reverse_delete_ipv6($server_id, $ip6) - { - - return self::delete("instances/{$server_id}/ipv6/reverse/{$ip6}"); - } - - /** - * Reboot server - * @see https://www.vultr.com/api/#operation/reboot-instance - * @param int $server_id - * @return int HTTP response code - */ - public function reboot($server_id) - { - return self::post("instances/{$server_id}/reboot"); - } - - /** - * Halt server - * @see https://www.vultr.com/api/#operation/halt-instances - * @param int $server_id - * @return int HTTP response code - */ - public function halt($server_id) - { - $args = array('instance_ids' => array((int)$server_id)); - return self::post('instances/halt', $args); - } - - /** - * Start server - * @see https://www.vultr.com/api/#operation/start-instance - * @param int $server_id - * @return int HTTP response code - */ - public function start($server_id) - { - return self::post("instances/{$server_id}/start"); - } - - /** - * Destroy server - * @see https://www.vultr.com/api/#operation/delete-instance - * @param int $server_id - * @return int HTTP response code - */ - public function destroy($server_id) - { - //$args = array('SUBID' => (int)$server_id); - return self::delete("instances/{$server_id}"); - } - - /** - * Reinstall OS on an instance - * @see https://www.vultr.com/api/#operation/reinstall-instance - * @param int $server_id - * @return int HTTP response code - */ - public function reinstall($server_id, $hostname='') - { - $args = array('hostname' => $hostname); - return self::post("instances/{$server_id}/reinstall", $args); - } - - /** - * Set server label - * @see https://www.vultr.com/api/#operation/update-instance - * @param int $server_id - * @param string $label - * @return int HTTP response code - */ - public function label_set($server_id, $label) - { - $args = array( - //'SUBID' => (int)$server_id, - 'label' => $label - ); - return self::patch("instances/{$server_id}", $args); - } - - /** - * Restore Server Snapshot - * @see https://www.vultr.com/api/#operation/restore-instance - * @param int $server_id - * @param string $snapshot_id Hexadecimal string with Restore ID - * @return int HTTP response code - */ - public function restore_snapshot($server_id, $snapshot_id) - { - $args = array( - //'backup_id' => (int)$server_id, - 'snapshot_id' => preg_replace('/[^a-f0-9]/', '', $snapshot_id) - ); - return self::post("instances/{$server_id}/restore", $args); - } - - /** - * Restore Backup - * @see https://www.vultr.com/api/#operation/restore-instance - * @param int $server_id - * @param string $backup_id - * @return int HTTP response code - */ - public function restore_backup($server_id, $backup_id) - { - $args = array( - //'SUBID' => $server_id, - 'backup_id' => $backup_id - ); - return self::post("instances/{$server_id}/restore", $args); - } - - /** - * List Backups - * @see https://www.vultr.com/api/#operation/list-backups - * @return mixed - */ - public function backup_list() - { - return self::get('backups'); - } - - /** - * Server Create - * @see https://www.vultr.com/api/#operation/create-instance - * @param $config - * @return bool|int|mixed|string - */ - public function create($config) - { - try - { - self::server_available((int)$config['DCID'], (int)$config['VPSPLANID']); - } - catch (Exception $e) - { - return FALSE; - } - - return self::post('instances', $config); - } - - /** - * SSH Keys List method - * @see https://www.vultr.com/api/#sshkey_sshkey_list - * @return FALSE if no SSH keys are available - * @return mixed with whatever ssh keys get returned - */ - public function sshkeys_list() - { - $try = self::get('ssh-keys'); - if (sizeof($try) < 1) - { - return FALSE; - } - return $try; - } - - /** - * SSH Keys Create method - * @see https://www.vultr.com/api/#sshkey_sshkey_create - * @param string $name - * @param string $key [openssh formatted public key] - * @return FALSE if no SSH keys are available - * @return mixed with whatever ssh keys get returned - */ - public function sshkey_create($name, $key) - { - $args = array( - 'name' => $name, - 'ssh_key' => $key - ); - return self::post('ssh-keys', $args); - } - - /** - * SSH Keys Update method - * @see https://www.vultr.com/api/#sshkey_sshkey_update - * @param string $key_id - * @param string $name - * @param string $key [openssh formatted public key] - * @return int HTTP response code - */ - public function sshkey_update($key_id, $name, $key) - { - $args = array( - 'SSHKEYID' => $key_id, - 'name' => $name, - 'ssh_key' => $key - ); - return self::patch('sshkey/update', $args); - } - - /** - * SSH Keys Destroy method - * @see https://www.vultr.com/api/#sshkey_sshkey_destroy - * @param string $key_id - * @return int HTTP response code - */ - public function sshkey_destroy($key_id) - { - $args = array('SSHKEYID' => $key_id); - return self::delete('sshkey/destroy', $args); - } - - /** - * GET Method - * @param string $method - * @param mixed $args - */ - public function get($method, $args = FALSE) - { - $this->request_type = 'GET'; - $this->get_code = false; - return self::query($method, $args); - } - - - /** - * DELETE Method - * @param $method - * @param $args - * @return bool|int|mixed|string - */ - public function delete($method, $args) - { - $this->request_type = 'DELETE'; - return self::query($method, $args); - } - - - // /** - // * CODE Method - // * @param string $method - // * @param mixed $args - // * @return mixed if no exceptions thrown - // * */ - // public function code($method, $args = FALSE) - // { - // $this->request_type = 'POST'; - // $this->get_code = true; - // return self::query($method, $args); - // } - - /** - * PATCH Method - * @param $method - * @param $args - * @return bool|int|mixed|string - */ - public function patch($method, $args) - { - $this->request_type = 'PATCH'; - return self::query($method, $args); - } - - /** - * POST Method - * @param $method - * @param $args - * @return bool|int|mixed|string - */ - public function post($method, $args) - { - $this->request_type = 'POST'; - return self::query($method, $args); - } - - /** - * PUT Method - * @param $method - * @param $args - * @return bool|int|mixed|string - */ - public function put($method, $args) - { - $this->request_type = 'PUT'; - return self::query($method, $args); - } - - /** - * API Query Function - * @param string $method - * @param mixed $args - */ - private function query($method, $args) - { - $methodArray = explode('/', $method); - $apiRequiredArray = array( - 'account', - 'auth', - 'backup', - 'baremetal', - 'block', - 'dns', - 'firewall', - 'iso', - 'network', - 'plans', - 'reservedip', - 'server', - 'snapshot', - 'sshkey', - 'startupscript', - 'user', - 'type', - 'per_page', - 'instance_id', - 'tag', - 'label', - 'main_ip', - 'cursor' - ); - - $url = $this->endpoint . $method; - $apiRequired = false; - - if ($this->debug) - { - echo $this->request_type . ' ' . $url . PHP_EOL; - } - - $_defaults = array( - CURLOPT_USERAGENT => sprintf('%s v%s (%s) - WHMCS Module', $this->agent, $this->version, 'https://github.com/whattheserver/whmcs-vultr'), - CURLOPT_HEADER => 0, - CURLOPT_VERBOSE => 0, - CURLOPT_SSL_VERIFYPEER => 0, - CURLOPT_SSL_VERIFYHOST => 0, - CURLOPT_HTTP_VERSION => '1.0', - CURLOPT_FOLLOWLOCATION => 0, - CURLOPT_FRESH_CONNECT => 1, - CURLOPT_RETURNTRANSFER => 1, - CURLOPT_FORBID_REUSE => 1, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTPHEADER => array('Accept: application/json') - ); - - if (in_array($methodArray[0], $apiRequiredArray)) - { - array_push($_defaults[CURLOPT_HTTPHEADER], "Authorization: Bearer $this->api_token"); - $apiRequired = true; - } - - $cacheable = false; - switch ($this->request_type) - { - - case 'POST': - $post_data = http_build_query($args); - $_defaults[CURLOPT_URL] = $url; - $_defaults[CURLOPT_POST] = 1; - $_defaults[CURLOPT_POSTFIELDS] = $post_data; - break; - - case 'PUT': - $post_data = http_build_query($args); - $_defaults[CURLOPT_URL] = $url; - $_defaults[CURLOPT_CUSTOMREQUEST] = 'PUT'; - $_defaults[CURLOPT_POSTFIELDS] = $post_data; - break; - - case 'PATCH': - $post_data = http_build_query($args); - $_defaults[CURLOPT_URL] = $url; - $_defaults[CURLOPT_CUSTOMREQUEST] = 'PATCH'; - $_defaults[CURLOPT_POSTFIELDS] = $post_data; - break; - - case 'DELETE': - //$post_data = http_build_query($args); - $_defaults[CURLOPT_URL] = $url; - $_defaults[CURLOPT_CUSTOMREQUEST] = 'DELETE'; - //$_defaults[CURLOPT_POSTFIELDS] = $post_data; - break; - - case 'GET': - if ($args !== FALSE) - { - $get_data = http_build_query($args); - $_defaults[CURLOPT_URL] = $url . '?' . $get_data; - } - else - { - $_defaults[CURLOPT_URL] = $url; - } - - $cacheable = true; - $response = $this->serveFromCache($_defaults[CURLOPT_URL]); - if ($response !== false) - { - $this->response_code = 200; - return $response; - } - break; - - default: - break; - } - - // To avoid rate limit hits - if ($this->readLast() == time() && $apiRequired) - { - usleep(333, 334); - } - - $apisess = curl_init(); - curl_setopt_array($apisess, $_defaults); - $response = curl_exec($apisess); - $httpCode = curl_getinfo($apisess, CURLINFO_HTTP_CODE); - logModuleCall('Vultr', $url, $args, "HTTP Code: " . $httpCode . "\n" . $response); - $this->writeLast(); - - /** - * Check to see if there were any API exceptions thrown - * If so, then error out, otherwise, keep going. - */ - try - { - self::isAPIError($apisess, $response); - } - catch (Exception $e) - { - curl_close($apisess); - $message = $e->getMessage() . PHP_EOL; - $this->message = $message; - return $message; - } - - /** - * Close our session - * Return the decoded JSON response - */ - curl_close($apisess); - $obj = json_decode($response, true); - - if ($this->get_code) - { - return (int)$this->response_code; - } - - if ($cacheable) - { - $this->saveToCache($url, $response); - } - else - { - $this->purgeCache($url); - } - - return $obj; - } - - public function getCode() - { - return (int)$this->response_code; - } - - public function checkConnection() - { - return $this->getCode() == 200 ? true : false; - } - - public function getMessage() - { - return $this->message; - } - - /** - * API Error Handling - * @param cURL_Handle $response_obj - * @param string $response - * @throws Exception if invalid API location is provided - * @throws Exception if API token is missing from request - * @throws Exception if API method does not exist - * @throws Exception if Internal Server Error occurs - * @throws Exception if the request fails otherwise - */ - public function isAPIError($response_obj, $response) - { - - $code = curl_getinfo($response_obj, CURLINFO_HTTP_CODE); - $this->response_code = $code; - - if ($this->debug) - { - echo $code . PHP_EOL; - } - - switch ($code) - { - case 200: - break; - case 201: - break; - case 202: - break; - case 204: - break; - case 400: - throw new Exception('400: Bad Request'); - break; - case 401: - throw new Exception('401: Unauthorized'); - break; - case 403: - throw new Exception('403: Forbidden'); - break; - case 404: - throw new Exception('404: Not Found'); - break; - case 500: - throw new Exception('500: Internal Server Error'); - break; - case 503: - throw new Exception('503: Service Unavailable. Your request exceeded the API rate limit.'); - break; - case 412: - throw new Exception('Request failed: ' . $response); - break; - default: - break; - } - } - - protected function serveFromCache($url) - { - // garbage collect 5% of the time - if (mt_rand(0, 19) == 0) - { - $files = glob("$this->cache_dir/*"); - $old = time() - ($this->cache_ttl * 2); - foreach ($files as $file) - { - if (filemtime($file) < $old) - { - unlink($old); - } - } - } - - $hash = md5($url); - $group = $this->groupFromUrl($url); - $file = "$this->cache_dir/$group-$hash"; - if (file_exists($file) && filemtime($file) > (time() - $this->cache_ttl)) - { - $response = file_get_contents($file); - $obj = json_decode($response, true); - return $obj; - } - return false; - } - - protected function saveToCache($url, $json) - { - if (!file_exists($this->cache_dir)) - { - mkdir($this->cache_dir); - } - - $hash = md5($url); - $group = $this->groupFromUrl($url); - $file = "$this->cache_dir/$group-$hash"; - file_put_contents($file, $json); - } - - protected function groupFromUrl($url) - { - $group = 'default'; - if (preg_match('@/v1/([^/]+)/@', $url, $match)) - { - return $match[1]; - } - } - - protected function purgeCache($url) - { - $group = $this->groupFromUrl($url); - $files = glob("$this->cache_dir/$group-*"); - foreach ($files as $file) - { - unlink($file); - } - } - - protected function writeLast() - { - if (!file_exists($this->cache_dir)) - { - mkdir($this->cache_dir); - } - - file_put_contents("$this->cache_dir/last", time()); - } - - protected function readLast() - { - if (file_exists("$this->cache_dir/last")) - { - return file_get_contents("$this->cache_dir/last"); - } - } - } +if (!class_exists('VultrAPI2')) { + /** + * Vultr.com API Client + * @package vultr + * @version 2.0 + * @author https://github.com/whattheserver/whmcs-vultr + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://github.com/whattheserver/whmcs-vultr/ + */ + class VultrAPI2 + { + + /** + * API Token + * @access private + * @type string $api_token Vultr.com API token + * @see https://my.vultr.com/settings/ + */ + private $api_token = ''; + + /** + * API Endpoint + * @access public + * @type string URL for Vultr.com API + */ + public $endpoint = 'https://api.vultr.com/v2/'; + + /** + * Current Version + * @access public + * @type string Current version number + */ + public $version = '2.0'; + + /** + * User Agent + * @access public + * @type string API User-Agent string + */ + public $agent = 'Vultr.com API Client'; + + /** + * Debug Variable + * @access public + * @type bool Debug API requests + */ + public $debug = true; + + /** + * Snapshots Variable + * @access public + * @type mixed Array to store snapshot IDs + */ + public $snapshots = array(); + + /** + * Plans Variable + * @access public + * @type mixed Array to store VPS Plan IDs + */ + public $plans = array(); + + /** + * Regions Variable + * @access public + * @type mixed Array to store available regions + */ + public $regions = array(); + + /** + * Scripts Variable + * @access public + * @type mixed Array to store startup scripts + */ + public $scripts = array(); + + /** + * Servers Variable + * @access public + * @type mixed Array to store server data + */ + public $servers = array(); + + /** + * Account Variable + * @access public + * @type mixed Array to store account data + */ + public $account = array(); + + /** + * OS List Variable + * @access public + * @type mixed Array to store OS list + */ + public $oses = array(); + + /** + * SSH Keys variable + * @access public + * @type mixed Array to store SSH keys + * */ + public $ssh_keys = array(); + + /** + * Response code variable + * @access public + * @type int Holds HTTP response code from API + * */ + public $response_code = 0; + + /** + * Response code variable + * @access public + * @type bool Determines whether to include the response code, default: false + * */ + public $get_code = false; + + /** + * Cache ttl for all get requests + * @access public + * $type int TTL in seconds + */ + public $cache_ttl = 1; + public $message = ''; + + /** + * Cache folder + * @access public + * $type string Cache dir + */ + public $cache_dir = '/tmp/vultr-api-client-cache'; + private $request_type; + + /** + * Constructor function + * @param string $token + * @param int $cache_ttl + * @return void + * @see https://my.vultr.com/settings/ + */ + public function __construct(string $token, $cache_ttl = 1) + { + $this->api_token = $token; + $this->cache_ttl = $cache_ttl; + $this->account = self::account_info(); + } + + /** + * Get Account info + * @see https://www.vultr.com/api/#tag/account + * @return mixed + */ + public function account_info() + { + return self::get('account'); + } + + /** + * Get OS list + * @see https://www.vultr.com/api/#operation/list-os + * @return mixed + */ + public function os_list() + { + return self::get('os'); + } + + /** + * OS Upgrade/Change Options + * @see https://www.vultr.com/api/#operation/get-instance-upgrades + * @see + * @param string $instanceid + * @return mixed + */ + public function os_change_list(string $instanceid) + { + return self::get("instances/{$instanceid}/upgrades?type=os"); + } + + /** + * OS Change/ Reinstall + * @see https://www.vultr.com/api/#operation/update-instance + * @see + * @param string $instanceid + * @param string $osid // https://www.vultr.com/api/#operation/list-isos + * @return mixed + */ + public function os_change(string $instanceid, string $osid) + { + return self::patch("instances/{$instanceid}", array('os_id' => $osid)); + } + + /** + * List available ISOs in your account. + * @see https://www.vultr.com/api/#iso_list + * @return mixed Available ISO images + * */ + public function iso_list() + { + return self::get('iso'); + } + + /** + * List all Vultr Public ISOs. + * @see https://www.vultr.com/api/#operation/list-public-isos + * @return array Available ISO images + * */ + public function public_iso_list() + { + return self::get('iso-public'); + } + + + /** + * Attach an ISO to an Instance. + * @see https://www.vultr.com/api/#operation/attach-instance-iso + * @param string $instanceid AKA Instance ID: 35sdw3f-234w-5678-e89g-2adfwebiuewib + * @param string $isoid cb676a46-66fd-4dfb-b839-443f2e6c0b60 + * @return mixed 202|400|401|404 + */ + public function attach_iso(string $instanceid, string $isoid) + { + return self::post("instances/{$instanceid}/iso/attach", array('iso_id' => $isoid)); + } + + /** + * Detach ISO + * @see https://www.vultr.com/api/#operation/detach-instance-iso + * @param string $instanceid + * @return mixed + */ + public function detach_iso(string $instanceid) + { + return self::post("instances/{$instanceid}/iso/detach", []); + } + + /** + * Get ISO Status + * @see https://www.vultr.com/api/#operation/get-instance-iso-status + * @param string $instanceid + * @return mixed + */ + public function iso_status(string $instanceid) + { + return self::get("instances/{$instanceid}/iso"); + } + + /** + * List available snapshots + * @see https://www.vultr.com/api/#snapshot_snapshot_list + * @return mixed + */ + public function snapshot_list() + { + return self::get('snapshots'); + } + + /** + * Destroy snapshot + * @see https://www.vultr.com/api/#snapshot_destroy + * @param string $snapshot_id Example: c68bcc12-7852-4b08-9294-b81b6e7a728f + * @return int HTTP response code + */ + public function snapshot_destroy(string $snapshot_id) + { + //$args = array('SNAPSHOTID' => $snapshot_id); + return self::delete("snapshots/{$snapshot_id}"); + } + + /** + * Create snapshot + * @see https://www.vultr.com/api/#operation/create-snapshot + * @param string $instanceid + * @param $description + * @return bool|int|mixed|string + */ + public function snapshot_create(string $instanceid, $description) + { + $desc = preg_replace('/\s+/', '_', $description); + $args = array('instance_id' => $instanceid, 'description' => $desc); + return self::post('snapshots', $args); + } + + /** + * List all DNS Domains in your account. + * @see https://www.vultr.com/api/#operation/list-dns-domains + * @return int|mixed|string + */ + public function dns_list() + { + return self::get('domains'); + } + + /** + * Create Domain + * @see https://www.vultr.com/api/#operation/create-dns-domain + * @param string $domain Your registered DNS Domain name. + * @param string|null $ip The default IP address for your DNS Domain. If omitted an empty domain zone will be created. + * @param bool $dns_sec Enable or disable DNSSEC. + * @return bool|int|mixed|string + */ + public function domain_create(string $domain, string $ip=null, bool $dns_sec=false) + { + $args = array('domain' => $domain); + if ($ip !== null) { + $args['ip'] = $ip; + } + if ($dns_sec !== false) { + $args['dns_sec'] = $dns_sec; + } + return self::post('domains', $args); + } + + /** + * Delete Domain + * @see https://www.vultr.com/api/#operation/delete-dns-domain + * @param string $domain + * @return bool|int|mixed|string + */ + public function domain_delete(string $domain) + { + return self::delete("domains/{$domain}"); + } + + /** + * Get the DNS records for the Domain. + * @param $domain + * @see https://www.vultr.com/api/#operation/list-dns-domain-records + * @return int|mixed|string + */ + public function dns_records($domain) + { + return self::get("domains/{$domain}/records"); + } + + /** + * Create a DNS record for a domain. + * @see https://www.vultr.com/api/#operation/create-dns-domain-record + * @param $domain + * @param $args + * @return bool|int|mixed|string + */ + public function create_record($domain, $args) + { + return self::post("domains/{$domain}/records", $args); + } + + /** + * Delete a DNS record. + * @see https://www.vultr.com/api/#operation/delete-dns-domain-record + * @param string $domain The DNS Domain. + * @param string $recordid The DNS Record id. + * @return bool|int|mixed|string + */ + public function delete_record(string $domain, string $recordid) + { + return self::delete("domains/{$domain}/records/{$recordid}"); + } + + /** + * Update the information for a DNS record. All attributes are optional. + * If not set, the attributes will retain their original values. + * @see https://www.vultr.com/api/#operation/update-dns-domain-record + * @param $args + * @return bool|int|mixed|string + */ + public function update_record($args) + { + $domain = $args['domain']; + $recordid = $args['RECORDID']; + unset($args['domain']); + unset($args['RECORDID']); + return self::patch("domains/{$domain}/records/{$recordid}", $args); + } + + /** + * Update SOA information + * @see https://www.vultr.com/api/#operation/update-dns-domain-soa + * @param array $args : ["domain" => $domain, "nsprimary" => $nameServer1, "email" => $email] + * @return bool|int|mixed|string + */ + public function soa_update(array $args) + { + $domain = $args['domain']; + unset($args['domain']); + return self::patch("domains/{$domain}/soa", $args); + } + + /** + * Get SOA information for the DNS Domain. + * @see https://www.vultr.com/api/#operation/get-dns-domain-soa + * @param string $domain + * @return int|mixed|string + */ + public function soa_info(string $domain) + { + return self::get("domains/{$domain}/soa"); + } + + /** + * Get Available Instance Upgrades + * @see https://www.vultr.com/api/#operation/get-instance-upgrades + * @param string $instanceid + * @return int|mixed|string + */ + public function upgrade_plan_list(string $instanceid) + { + return self::get("instances/{$instanceid}/upgrades" . '?type=plans'); + } + + /** + * Upgrade Plan / Update Instance + * @see https://www.vultr.com/api/#operation/update-instance + * @param string $instanceid + * @param string $vpsplanid // https://www.vultr.com/api/#operation/list-plans + * @return void + */ + public function upgrade_plan(string $instanceid, string $vpsplanid) + { + return self::patch("instances/{$instanceid}", ['plan' => $vpsplanid]); + } + + /** + * List available applications + * @see https://www.vultr.com/api/#app_app_list + * @return array Available applications + * */ + public function app_list(): array + { + $vultr_apps_nice = []; + $apps = self::get('applications'); + + foreach ($apps as $app) { + foreach ($app as $key=>$value) { + if (!empty($value['id'])) { + $app_fixed = [ + "APPID" => $value['id'], + "name" => $value['name'], + "short_name" => $value['short_name'], + "deploy_name" => $value['deploy_name'], + ]; + $vultr_apps_nice[$value['id']] = $app_fixed; + } + } + } + return $vultr_apps_nice; + } + + /** + * List available applications for instance + * @see https://www.vultr.com/api/#operation/get-instance-upgrades + * @param string $instanceid + * @return mixed Available applications + */ + public function app_change_list(string $instanceid) + { + return self::get("instances/{$instanceid}/upgrades?type=applications"); + } + + /** + * Reinstall via Application ID + * @see https://www.vultr.com/api/#operation/update-instance + * @param string $instanceid // server + * @param integer $appid // Available applications from https://www.vultr.com/api/#operation/list-applications + * @return bool|int|mixed|string + */ + public function app_change(string $instanceid, int $appid) + { + return self::patch("instances/{$instanceid}", ['app_id' => $appid]); + } + + /** + * List available plans + * @see https://www.vultr.com/api/#plans_plan_list + * @return mixed + */ + public function plans_list() + { + return self::get('plans'); + } + + /** + * List available regions + * @see https://www.vultr.com/api/#regions_region_list + * @return mixed + */ + public function regions_list() + { + return self::get('regions'); + } + + /** + * Determine region availability + * @see https://www.vultr.com/api/#operation/list-available-compute-region + * @param string $region_id + * @return mixed VPS plans available at given region + */ + public function regions_availability(string $region_id) + { + return self::get("regions/{$region_id}/availability"); + } + + + /** + * Get Instance userdata + * Get the user-supplied, base64 encoded user data for an Instance. + * @see https://www.vultr.com/api/#operation/get-instance-userdata + * @param string $instanceid + * @return int|mixed|string + */ + public function server_userData(string $instanceid) + { + return self::get("instances/{$instanceid}/user-data"); + } + + /** + * List startup scripts + * @see https://www.vultr.com/api/#operation/list-startup-scripts + * @return mixed List of startup scripts + */ + public function startupscript_list() + { + return self::get('startup-scripts'); + } + + /** + * Update startup script + * @see https://www.vultr.com/api/#operation/update-startup-script + * @param string $script_id + * @param string $name The name of the Startup Script. + * @param string $script The base-64 encoded Startup Script contents + * @param string $script_type The Startup Script type. boot (default) pxe + * @return int HTTP response code + */ + public function startupscript_update(string $script_id, string $name, string $script, $script_type='default') + { + $args = array( + 'type' => $script_type, + 'name' => $name, + 'script' => $script + ); + return self::patch("startup-scripts/{$script_id}", $args); + } + + /** + * Destroy startup script + * @see https://www.vultr.com/api/#startupscript_destroy + * @param string $script_id + * @return int HTTP response code + */ + public function startupscript_destroy(string $script_id) + { + return self::delete("startup-scripts/{$script_id}"); + } + + /** + * Create startup script + * @see https://www.vultr.com/api/#operation/create-startup-script + * @param string $script_name The name of the Startup Script. + * @param string $script_contents The base-64 encoded Startup Script. + * @param string $script_type boot (default) or pxe + * @return string Script ID: "id": "cb676a46-66fd-4dfb-b839-443f2e6c0b60" + */ + public function startupscript_create(string $script_name, string $script_contents, string $script_type) + { + $args = array( + 'name' => $script_name, + 'script' => $script_contents, + 'type' => $script_type + ); + $script = self::post('startup-scripts', $args); + return $script['startup_script']['id']; + } + + /** + * Server Available in Region + * @param string $region_id : https://www.vultr.com/api/#operation/list-regions + * @param string $plan_id : https://www.vultr.com/api/#operation/list-plans + * @throws Exception + */ + public function server_available(string $region_id, string $plan_id) + { + $availability = self::regions_availability($region_id); + if (!in_array($plan_id, $availability)) { + throw new Exception('Plan ID ' . $plan_id . ' is not available in region ' . $region_id); + } + } + + /** + * List servers + * @see https://www.vultr.com/api/#server_server_list + * @return mixed List of servers + */ + public function server_list() + { + return self::get('instances'); + } + + /** + * Display server bandwidth + * @see https://www.vultr.com/api/#operation/get-instance-bandwidth + * @param string $instanceid + * @return mixed Bandwidth history + */ + public function bandwidth(string $instanceid) + { + return self::get("instances/{$instanceid}/bandwidth"); + } + + /** + * List IPv4 Addresses allocated to specified server + * @see https://www.vultr.com/api/#operation/get-instance-ipv4 + * @param string $instanceid + * @return mixed IPv4 address list + */ + public function list_ipv4(string $instanceid) + { + $ipv4 = self::get("instances/{$instanceid}/ipv4"); + return $ipv4['ipv4s']; + } + + /** + * Create IPv4 address + * @see https://www.vultr.com/api/#operation/create-instance-ipv4 + * @param string $instanceid + * @param string Reboot server after adding IP: , default: yes + * @return int HTTP response code + * */ + public function ipv4_create(string $instanceid, $reboot='yes') + { + $args = array( + 'reboot' => ($reboot == 'yes' ? 'yes' : 'no') + ); + return self::post("instances/{$instanceid}/ipv4", $args); + } + + /** + * Destroy IPv4 Address + * @see https://www.vultr.com/api/#operation/delete-instance-ipv4 + * @param string $instanceid + * @param string $ip4 + * @return int HTTP response code + */ + public function destroy_ipv4(string $instanceid, string $ip4) + { + return self::delete("instances/{$instanceid}/ipv4/{$ip4}"); + } + + /** + * Set Reverse DNS for IPv4 address + * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv4 + * @param string $ip The IPv4 address. + * @param string $rdns The IPv4 reverse entry. + * @param string $instanceid + * @return int HTTP response code + */ + public function reverse_set_ipv4(string $ip, string $rdns, string $instanceid) + { + $args = [ + "ip" => $ip, + "reverse" => $rdns]; + + return self::post("instances/{$instanceid}/ipv4/reverse", $args); + } + + /** + * Set Default Reverse DNS for IPv4 address + * @see https://www.vultr.com/api/#operation/post-instances-instance-id-ipv4-reverse-default + * @param string $instanceid + * @param string $ip + * @return int HTTP response code + */ + public function reverse_default_ipv4(string $instanceid, string $ip) + { + $args = array( + 'ip' => $ip + ); + return self::post("instances/{$instanceid}/reverse/default", $args); + } + + /** + * List IPv6 addresses for specified server + * @see https://www.vultr.com/api/#operation/get-instance-ipv6 + * @param string $instanceid + * @return mixed IPv6 allocation info + */ + public function list_ipv6(string $instanceid) + { + $ipv6 = self::get("instances/{$instanceid}/ipv6"); + return $ipv6['ipv6s']; + } + + /** + * List Instance IPv6 Reverse + * @see https://www.vultr.com/api/#operation/list-instance-ipv6-reverse + * @param string $instanceid + * @return mixed IPv6 allocation info + */ + public function reverse_list_ipv6(string $instanceid) + { + $ipv6 = self::get("instances/{$instanceid}/ipv6/reverse"); + return $ipv6['reverse_ipv6s']; + } + + /** + * Get Application Information + * @see https://www.vultr.com/api/#operation/get-instance + * @param string $instanceid + * @return mixed Application Information + */ + public function get_app_info(string $instanceid) + { + $app_id = self::get("instances/{$instanceid}")['instance']['app_id']; + $app_info = self::app_list()[$app_id]['name']; + return $app_info['name']; + } + + + /** + * Set Reverse DNS for IPv6 address + * @see https://www.vultr.com/api/#operation/create-instance-reverse-ipv6 + * @param string $instanceid + * @param string $ipv6 + * @param string $rdns + * @return int HTTP response code + */ + public function reverse_set_ipv6(string $instanceid, string $ipv6, string $rdns) + { + $args = array( + 'ip' => $ipv6, + 'reverse' => $rdns + ); + return self::post("instances/{$instanceid}/ipv6/reverse", $args); + } + + /** + * Delete IPv6 Reverse DNS + * @see https://www.vultr.com/api/#operation/delete-instance-reverse-ipv6 + * @param string $instanceid + * @param string $ipv6 IPv6 address + * @return int HTTP response code + * */ + public function reverse_delete_ipv6(string $instanceid, string $ipv6) + { + return self::delete("instances/{$instanceid}/ipv6/reverse/{$ipv6}"); + } + + /** + * Reboot server + * @see https://www.vultr.com/api/#operation/reboot-instance + * @param string $instanceid + * @return int HTTP response code + */ + public function reboot(string $instanceid) + { + return self::post("instances/{$instanceid}/reboot", []); + } + + /** + * Halt server + * @see https://www.vultr.com/api/#operation/halt-instances + * @param string $instanceid + * @return int HTTP response code + */ + public function halt(string $instanceid) + { + $args = array('instance_ids' => array($instanceid)); + return self::post('instances/halt', $args); + } + + /** + * Start server + * @see https://www.vultr.com/api/#operation/start-instance + * @param string $instanceid + * @return int HTTP response code + */ + public function start(string $instanceid) + { + return self::post("instances/{$instanceid}/start"); + } + + /** + * Destroy server + * @see https://www.vultr.com/api/#operation/delete-instance + * @param string $instanceid + * @return int HTTP response code + */ + public function destroy(string $instanceid) + { + return self::delete("instances/{$instanceid}"); + } + + /** + * Reinstall OS on an instance + * @see https://www.vultr.com/api/#operation/reinstall-instance + * @param string $instanceid + * @param string $hostname + * @return int HTTP response code + */ + public function reinstall(string $instanceid, $hostname='') + { + $args = array('hostname' => $hostname); + return self::post("instances/{$instanceid}/reinstall", $args); + } + + /** + * Set server label + * @see https://www.vultr.com/api/#operation/update-instance + * @param string $instanceid + * @param string $label + * @return int HTTP response code + */ + public function label_set(string $instanceid, string $label) + { + $args = array( + 'label' => $label + ); + return self::patch("instances/{$instanceid}", $args); + } + + /** + * Restore Server Snapshot + * @see https://www.vultr.com/api/#operation/restore-instance + * @param string $instanceid The Instance ID. + * @param string $snapshot_id The Snapshot id used to restore this instance. + * @return int HTTP response code + */ + public function restore_snapshot(string $instanceid, string $snapshot_id) + { + $args = array( + 'snapshot_id' => $snapshot_id + ); + return self::post("instances/{$instanceid}/restore", $args); + } + + /** + * Restore Backup + * @see https://www.vultr.com/api/#operation/restore-instance + * @param string $instanceid + * @param string $backup_id + * @return int HTTP response code + */ + public function restore_backup(string $instanceid, string $backup_id) + { + $args = array( + 'backup_id' => $backup_id + ); + return self::post("instances/{$instanceid}/restore", $args); + } + + /** + * List Backups + * @see https://www.vultr.com/api/#operation/list-backups + * @return mixed + */ + public function backup_list() + { + return self::get('backups'); + } + + /** + * List Instance specific backups + * @see https://www.vultr.com/api/#operation/list-backups + * @param $instanceid + * @return mixed + */ + public function instance_backup_list($instanceid) + { + return self::get("backups" ."?instance_id={$instanceid}"); + } + + /** + * Server Create + * @see https://www.vultr.com/api/#operation/create-instance + * @param $config + * @return bool|int|mixed|string + */ + public function create($config) + { + try { + self::server_available((int)$config['DCID'], (int)$config['VPSPLANID']); + } catch (Exception $e) { + return false; + } + + return self::post('instances', $config); + } + + /** + * SSH Keys List method + * @see https://www.vultr.com/api/#sshkey_sshkey_list + * @return FALSE if no SSH keys are available + * @return mixed with whatever ssh keys get returned + */ + public function sshkeys_list() + { + $try = self::get('ssh-keys'); + if (sizeof($try) < 1) { + return false; + } + return $try; + } + + /** + * SSH Keys Create method + * @see https://www.vultr.com/api/#sshkey_sshkey_create + * @param string $name + * @param string $key [openssh formatted public key] + * @return FALSE if no SSH keys are available + * @return mixed with whatever ssh keys get returned + */ + public function sshkey_create(string $name, string $key) + { + $args = array( + 'name' => $name, + 'ssh_key' => $key + ); + return self::post('ssh-keys', $args); + } + + /** + * SSH Keys Update method + * @see https://www.vultr.com/api/#sshkey_sshkey_update + * @param string $key_id + * @param string $name + * @param string $key [openssh formatted public key] + * @return int HTTP response code + */ + public function sshkey_update(string $key_id, string $name, string $key) + { + $args = array( + 'SSHKEYID' => $key_id, + 'name' => $name, + 'ssh_key' => $key + ); + return self::patch('sshkey/update', $args); + } + + /** + * SSH Keys Destroy method + * @see https://www.vultr.com/api/#sshkey_sshkey_destroy + * @param string $key_id + * @return int HTTP response code + */ + public function sshkey_destroy(string $key_id) + { + $args = array('SSHKEYID' => $key_id); + return self::delete('sshkey/destroy', $args); + } + + /** + * GET Method + * @param string $method + * @param mixed $args + * @return int|mixed|string + */ + public function get(string $method, $args = false) + { + $this->request_type = 'GET'; + $this->get_code = false; + return self::query($method, $args); + } + + + /** + * DELETE Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function delete($method, $args=[]) + { + $this->request_type = 'DELETE'; + return self::query($method, $args); + } + + + /** + * PATCH Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function patch($method, $args) + { + $this->request_type = 'PATCH'; + return self::query($method, $args); + } + + /** + * POST Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function post($method, $args) + { + $this->request_type = 'POST'; + return self::query($method, $args); + } + + /** + * PUT Method + * @param $method + * @param $args + * @return bool|int|mixed|string + */ + public function put($method, $args) + { + $this->request_type = 'PUT'; + return self::query($method, $args); + } + + /** + * API Query Function + * @param string $method + * @param mixed $args + * @return int|mixed|string + */ + private function query(string $method, $args) + { + $methodArray = explode('/', $method); + $apiRequiredArray = array( + 'account', + 'auth', + 'backup', + 'backups', + 'baremetal', + 'blocks', + 'dns', + 'firewalls', + 'iso', + 'network', + 'plans', + 'reservedip', + 'reserved-ips', + 'server', + 'snapshots', + 'sshkey', + 'ssh-keys', + 'startupscript', + 'startup-scripts', + 'user', + 'users', + 'type', + 'per_page', + 'instance_id', + 'tag', + 'label', + 'main_ip', + 'cursor', + 'instances', + 'os', + 'domains', + 'load-balancers', + 'bare-metals', + 'object-storage', + 'private-networks', + + ); + + $url = $this->endpoint . $method; + $apiRequired = false; + + if ($this->debug) { + echo $this->request_type . ' ' . $url . PHP_EOL; + } + + $_defaults = array( + CURLOPT_USERAGENT => sprintf('%s v%s (%s) - WHMCS Module', $this->agent, $this->version, 'https://github.com/whattheserver/vultr-provisioning-module/'), + CURLOPT_HEADER => 0, + CURLOPT_VERBOSE => 0, + CURLOPT_SSL_VERIFYPEER => 0, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_HTTP_VERSION => '1.0', + CURLOPT_FOLLOWLOCATION => 0, + CURLOPT_FRESH_CONNECT => 1, + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_FORBID_REUSE => 1, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTPHEADER => array('Accept: application/json') + ); + + if (in_array($methodArray[0], $apiRequiredArray)) { + array_push($_defaults[CURLOPT_HTTPHEADER], "Authorization: Bearer $this->api_token"); + $apiRequired = true; + } + + $cacheable = false; + switch ($this->request_type) { + + case 'POST': + + $post_data = json_encode($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_POST] = 1; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'PUT': + $post_data = json_encode($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'PUT'; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'PATCH': + $post_data = json_encode($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'PATCH'; + $_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'DELETE': + //$post_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url; + $_defaults[CURLOPT_CUSTOMREQUEST] = 'DELETE'; + //$_defaults[CURLOPT_POSTFIELDS] = $post_data; + break; + + case 'GET': + if ($args !== false) { + $get_data = http_build_query($args); + $_defaults[CURLOPT_URL] = $url . '?' . $get_data; + } else { + $_defaults[CURLOPT_URL] = $url; + } + + $cacheable = true; + $response = $this->serveFromCache($_defaults[CURLOPT_URL]); + if ($response !== false) { + $this->response_code = 200; + return $response; + } + break; + + default: + break; + } + + // To avoid rate limit hits + if ($this->readLast() == time() && $apiRequired) { + usleep(333); + } + + $apisess = curl_init(); + curl_setopt_array($apisess, $_defaults); + $response = curl_exec($apisess); + $httpCode = curl_getinfo($apisess, CURLINFO_HTTP_CODE); + // logModuleCall('Vultr', $url, $args, "HTTP Code: " . $httpCode . "\n" . $response); + $this->writeLast(); + + /** + * Check to see if there were any API exceptions thrown + * If so, then error out, otherwise, keep going. + */ + try { + self::isAPIError($apisess, $response); + } catch (Exception $e) { + curl_close($apisess); + $message = $e->getMessage() . PHP_EOL; + $this->message = $message; + return $message; + } + + /** + * Close our session + * Return the decoded JSON response + */ + curl_close($apisess); + $obj = json_decode($response, true); + + if ($this->get_code) { + return (int)$this->response_code; + } + + if ($cacheable) { + $this->saveToCache($url, $response); + } else { + $this->purgeCache($url); + } + + return $obj; + } + + public function getCode(): int + { + return (int)$this->response_code; + } + + public function checkConnection(): bool + { + return $this->getCode() == 200; + } + + public function getMessage(): string + { + return $this->message; + } + + /** + * API Error Handling + * @param cURL_Handle $response_obj + * @param string $response + * @throws Exception if invalid API location is provided + * @throws Exception if API token is missing from request + * @throws Exception if API method does not exist + * @throws Exception if Internal Server Error occurs + * @throws Exception if the request fails otherwise + */ + public function isAPIError($response_obj, string $response) + { + $code = curl_getinfo($response_obj, CURLINFO_HTTP_CODE); + $this->response_code = $code; + + if ($this->debug) { + echo $code . PHP_EOL; + } + + switch ($code) { + case 400: + throw new Exception('400: Bad Request'); + break; + case 401: + throw new Exception('401: Unauthorized'); + break; + case 403: + throw new Exception('403: Forbidden'); + break; + case 404: + throw new Exception('404: Not Found'); + break; + case 500: + throw new Exception('500: Internal Server Error'); + break; + case 503: + throw new Exception('503: Service Unavailable. Your request exceeded the API rate limit.'); + break; + case 412: + throw new Exception('Request failed: ' . $response); + break; + default: + case 200: + case 201: + case 202: + case 204: + break; + } + } + + protected function serveFromCache($url) + { + // garbage collect 5% of the time + if (mt_rand(0, 19) == 0) { + $files = glob("$this->cache_dir/*"); + $old = time() - ($this->cache_ttl * 2); + foreach ($files as $file) { + if (filemtime($file) < $old) { + unlink($old); + } + } + } + + $hash = md5($url); + $group = $this->groupFromUrl($url); + $file = "$this->cache_dir/$group-$hash"; + if (file_exists($file) && filemtime($file) > (time() - $this->cache_ttl)) { + $response = file_get_contents($file); + return json_decode($response, true); + } + return false; + } + + protected function saveToCache($url, $json) + { + if (!file_exists($this->cache_dir)) { + mkdir($this->cache_dir); + } + + $hash = md5($url); + $group = $this->groupFromUrl($url); + $file = "$this->cache_dir/$group-$hash"; + file_put_contents($file, $json); + } + + protected function groupFromUrl($url) + { + $group = 'default'; + if (preg_match('@/v1/([^/]+)/@', $url, $match)) { + return $match[1]; + } + } + + protected function purgeCache($url) + { + $group = $this->groupFromUrl($url); + $files = glob("$this->cache_dir/$group-*"); + foreach ($files as $file) { + unlink($file); + } + } + + protected function writeLast() + { + if (!file_exists($this->cache_dir)) { + mkdir($this->cache_dir); + } + + file_put_contents("$this->cache_dir/last", time()); + } + + protected function readLast() + { + if (file_exists("$this->cache_dir/last")) { + return file_get_contents("$this->cache_dir/last"); + } + } + } } From 453c76e9de1fcebbed0a23671b1e0eb51e529f4a Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 20:57:09 -0400 Subject: [PATCH 10/23] Update main.controller.php Fixed the subid not being properly saved into the tblcustomfields which causes it to not register as created. Should resolve: https://github.com/vultr/whmcs-vultr/issues/91 https://github.com/vultr/whmcs-vultr/issues/92 https://github.com/vultr/whmcs-vultr/issues/105 https://github.com/vultr/whmcs-vultr/issues/106 Tested with latest WHMCS Version: 8.1.3 PHP 7.3 and PHP7.4 Centos 7 --- servers/vultr/controller/main.controller.php | 42 +++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/servers/vultr/controller/main.controller.php b/servers/vultr/controller/main.controller.php index ad97a50..8a0d4fa 100755 --- a/servers/vultr/controller/main.controller.php +++ b/servers/vultr/controller/main.controller.php @@ -1,6 +1,6 @@ vultrAPI->create($vmParams); - - if (is_array($vm)) + + // For debugging only. Can comment out the create statement above and then uncomment the below to simulate being passed a SUBID/instanced id to confirm the weird issues. + // $vm = [ + // "SUBID" => "46109452", + // "v2_id" => "6593a82e-bd1f-4a5f-9396-322ffdd4bd22" + // ]; + + // die(var_dump($vm)); + // using if/else to detect v1 api subid/instance id or v2api + if (isset($vm['SUBID']) && mb_strlen($vm['SUBID']) == 8 ) { + $vmid = $vm['SUBID']; // $vm['SUBID'] or $vm['v2_id'] https://www.vultr.com/api/v1/#server_create + } elseif (isset($vm['v2_id'])) { + $vmid = $vm['v2_id']; // + } elseif (isset($vm['instance']['id'])) { + $vmid = $vm['instance']['id']; // $vm['instance']['id'] new v2API responses https://www.vultr.com/api/#operation/create-instance + } else { + $vmid = false; // no instance or server ID was found. + } + //die(var_dump($vmid)); + if ($vmid !== false) // Bail and show an error to contact support if no server id created or returned { - $this->addVMCustomFields($vm['SUBID']); + $this->addVMCustomFields($vmid); SessionHelper::setFlashMessage('success', LangHelper::T('main.create.created_success')); $this->redirect('clientarea.php?action=productdetails&id=' . $this->serviceID); } else { - SessionHelper::setFlashMessage('danger', $vm); + SessionHelper::setFlashMessage('danger', 'Server creation was unsuccessful! Please contact Support!. Do not try to recreate. It will fail.'); } } } @@ -372,27 +390,31 @@ public function createAction() } private function addVMCustomFields($SUBID) - { + { + $customField = Capsule::table('tblcustomfields') ->where('type', 'product') ->where('relid', $this->params['packageid']) ->where('fieldname', 'LIKE', 'subid|%')->get(); - if (count($customField) > 0) + if ($customField) { $customFieldValue = Capsule::table('tblcustomfieldsvalues') ->where('fieldid', $customField[0]->id) ->where('relid', $this->serviceID)->get(); - if (count($customFieldValue) > 0) - { + if ($customFieldValue) + { $customFieldValue = Capsule::table('tblcustomfieldsvalues') ->where('fieldid', $customField[0]->id) ->where('relid', $this->serviceID)->update(array('value' => $SUBID)); } else - { + { // die(" Die before insert normal :" . var_dump($this->serviceID).PHP_EOL); never hits here which was the old fallback and seems worthless?? Capsule::table('tblcustomfieldsvalues')->insert(array('fieldid' => $customField[0]->id, 'relid' => $this->serviceID, 'value' => $SUBID)); } + } + // die('Die before inserting tblcustomfieldsvalues '); // This is what was actually needed to fix the missing subid issue not being entered into tblcustomfieldsvalues. + Capsule::table('tblcustomfieldsvalues')->insert(array('fieldid' => $this->params['packageid'], 'relid' => $this->serviceID, 'value' => $SUBID)); } public function deleteAction() From 250c6f66619f9880493d0dfbe8f497d3082fe1ea Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 21:09:02 -0400 Subject: [PATCH 11/23] Update hooks.php --- servers/vultr/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/hooks.php b/servers/vultr/hooks.php index 8672818..05e32af 100755 --- a/servers/vultr/hooks.php +++ b/servers/vultr/hooks.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:09:59 -0400 Subject: [PATCH 12/23] Update vultr.helper.php --- servers/vultr/helper/vultr.helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/helper/vultr.helper.php b/servers/vultr/helper/vultr.helper.php index b6fa41f..bbc575e 100755 --- a/servers/vultr/helper/vultr.helper.php +++ b/servers/vultr/helper/vultr.helper.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:10:45 -0400 Subject: [PATCH 13/23] Update vultr.controller.php --- servers/vultr/controller/vultr.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/controller/vultr.controller.php b/servers/vultr/controller/vultr.controller.php index 3064d4e..7aca9ea 100755 --- a/servers/vultr/controller/vultr.controller.php +++ b/servers/vultr/controller/vultr.controller.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:11:29 -0400 Subject: [PATCH 14/23] Update sshkeys.controller.php --- servers/vultr/controller/sshkeys.controller.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/servers/vultr/controller/sshkeys.controller.php b/servers/vultr/controller/sshkeys.controller.php index 32f0e13..bae522e 100755 --- a/servers/vultr/controller/sshkeys.controller.php +++ b/servers/vultr/controller/sshkeys.controller.php @@ -1,6 +1,6 @@ getVultrAPI()) { $allowKeys = Capsule::table('vultr_sshkeys')->where('client_id', $this->clientID)->get(); - if (count($allowKeys) < 1) + // if (empty($allowKeys)) https://github.com/vultr/whmcs-vultr/pull/101/files#diff-e528d8e5801f95b469223f6b1d473b92f3699c420a7db69af5063ca8e61713b9 + if (count($allowKeys) < 1) { return array(); } From 6dc71eccb54b236034af895b48ffc98af424172c Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 21:12:07 -0400 Subject: [PATCH 15/23] Update snapshots.controller.php --- servers/vultr/controller/snapshots.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/controller/snapshots.controller.php b/servers/vultr/controller/snapshots.controller.php index fced006..5573135 100755 --- a/servers/vultr/controller/snapshots.controller.php +++ b/servers/vultr/controller/snapshots.controller.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:16:57 -0400 Subject: [PATCH 16/23] Update scripts.controller.php --- servers/vultr/controller/scripts.controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/vultr/controller/scripts.controller.php b/servers/vultr/controller/scripts.controller.php index de89b2e..22859bd 100755 --- a/servers/vultr/controller/scripts.controller.php +++ b/servers/vultr/controller/scripts.controller.php @@ -1,6 +1,6 @@ where('SCRIPTID', $id)->where('client_id', $this->clientID)->first(); - if (!empty($allow)) + if (!empty($allow)) // this may need to be fixed to if (count($allow) > 0) but have not tested changing it yet to count { if ($this->getVultrAPI()) { From 833bf527f18bd6f6af63e6ff2bae478bd8fc5e14 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 21:18:19 -0400 Subject: [PATCH 17/23] Update dns.controller.php --- servers/vultr/controller/dns.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/controller/dns.controller.php b/servers/vultr/controller/dns.controller.php index d487dd6..9b5d25f 100755 --- a/servers/vultr/controller/dns.controller.php +++ b/servers/vultr/controller/dns.controller.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:19:38 -0400 Subject: [PATCH 18/23] Update vultr.class.php --- servers/vultr/class/vultr.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/vultr/class/vultr.class.php b/servers/vultr/class/vultr.class.php index aa263d9..ec3102a 100755 --- a/servers/vultr/class/vultr.class.php +++ b/servers/vultr/class/vultr.class.php @@ -1,6 +1,6 @@ Date: Sun, 11 Apr 2021 21:24:12 -0400 Subject: [PATCH 19/23] Update hooks.php --- addons/vultr/hooks.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/vultr/hooks.php b/addons/vultr/hooks.php index 4145c23..413ceca 100755 --- a/addons/vultr/hooks.php +++ b/addons/vultr/hooks.php @@ -1,6 +1,6 @@ join("tblproductconfiglinks", "tblproductconfiglinks.pid", "=", "tblproducts.id") ->join("tblproductconfiggroups", "tblproductconfiggroups.id", "=", "tblproductconfiglinks.gid") ->join("tblproductconfigoptions", "tblproductconfigoptions.gid", "=", "tblproductconfiggroups.id") @@ -126,7 +126,7 @@ function getConfigOptionId($optionname) require_once 'Loader.php'; new main\Loader(); - $productInfo = WHMCS\Database\Capsule::table("tblproducts") + $productInfo = Capsule::table("tblproducts") ->select("tblproducts.configoption2", "tblproducts.servertype") ->where("tblproducts.id", "=", $_SESSION['cart']['products'][$_GET['i']]['pid']) ->first(); @@ -137,7 +137,7 @@ function getConfigOptionId($optionname) } $productPlanId = $productInfo->configoption2; - $apiToken = \WHMCS\Database\Capsule::table("tbladdonmodules") + $apiToken = Capsule::table("tbladdonmodules") ->select("tbladdonmodules.value") ->where("tbladdonmodules.module", "=", "vultr") ->where("tbladdonmodules.setting", "=", "apiToken") From 93bb86bb13dcea620dc7a300a0a988610295d692 Mon Sep 17 00:00:00 2001 From: WhatTheServer Date: Sun, 11 Apr 2021 21:25:17 -0400 Subject: [PATCH 20/23] Update Configuration.php bump version --- addons/vultr/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/vultr/Configuration.php b/addons/vultr/Configuration.php index a468890..430c6f3 100755 --- a/addons/vultr/Configuration.php +++ b/addons/vultr/Configuration.php @@ -51,7 +51,7 @@ class Configuration extends main\mgLibs\process\AbstractConfiguration * Module version * @var string */ - public $version = '2.0.4'; + public $version = '2.0.5'; /** * Module author From 508bcf87d61ce082aa1aeef144306965f0ec4312 Mon Sep 17 00:00:00 2001 From: Michael Ramsey Date: Sat, 3 Jul 2021 09:52:59 -0400 Subject: [PATCH 21/23] Updated changelog for release --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a22d960..d3e0489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Change Log +## v2.0.5 (2021-04-21) +### Bug +* Fixes Doesn't show server details in client area [#88](https://github.com/vultr/whmcs-vultr/issues/88) +* Fixes After WHMCS 8 upgrade server creation failed [#91](https://github.com/vultr/whmcs-vultr/issues/91) +* Fixes WHMCS 8.0.2 successfully created the virtual machine, but failed to manage it [#92](https://github.com/vultr/whmcs-vultr/issues/92) +* Fixes Virtual machine ID [#105](https://github.com/vultr/whmcs-vultr/issues/105) +* Can't deploy server in WHMCS 8.1.1 [#106](https://github.com/vultr/whmcs-vultr/issues/106) +### Features +* Various bug fixes +* Quality of life improvements + +### Changes +* Updated all deprecated +`use Illuminate\Database\Capsule\Manager as Capsule;` +To: +`use WHMCS\Database\Capsule;` + +As recommended by WHMCS. +https://developers.whmcs.com/advanced/db-interaction/ + +Please NOTE: That I have incorporated some, but NOT all of the fixes from [#101](https://github.com/vultr/whmcs-vultr/issues/101) +All original credit for those things should be attributed to @jazz7381 and that PR could most likely be closed as mine incorporates the working stuff from there and more. + +Also included is a pretty extensive port of the VultrAPI class to V2 which is not in use yet, but is pretty close to being able to be used. + +The main issue appears to have been in addVMCustomFields where it was failing to add the subid to tblcustomfieldsvalues +whattheserver@453c76e + +This in turn causes the creation to fail and allows customers to keep trying to create servers they thought failed but are detached from the client area and costing the Reseller money and time wasted going to clean those up and reattaching only one to the account manually. + ## v2.0.4 (2019-09-19) ### Bug * Fixes UI Issue where OS would reset upon save [#36](https://github.com/vultr/whmcs-vultr/pull/36) From 74bdd1bc0eb61b72493f53b48be70b3c2528fbbd Mon Sep 17 00:00:00 2001 From: Michael Ramsey Date: Sun, 2 Jan 2022 15:20:12 -0500 Subject: [PATCH 22/23] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a9c015..60098eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # WHMCS Module -## Note: This module is community driven, it is no longer actively maintained. +## Note: This module is community driven, it is no longer actively maintained. I recommend switching to the ModulesGarden one recently released. +https://www.modulesgarden.com/products/whmcs/vultr-vps ## System Requirements From b4f4941812243820a439175abc4877e860904b74 Mon Sep 17 00:00:00 2001 From: Michael Ramsey Date: Sun, 2 Jan 2022 15:20:30 -0500 Subject: [PATCH 23/23] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 60098eb..3a3e3cf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # WHMCS Module -## Note: This module is community driven, it is no longer actively maintained. I recommend switching to the ModulesGarden one recently released. +## Note: This module is community driven, it is no longer actively maintained. +I recommend switching to the ModulesGarden one recently released. https://www.modulesgarden.com/products/whmcs/vultr-vps ## System Requirements