#!/usr/bin/env php 0; } /** * geocodeAddress(): Use Google Geocode API to turn addresses into GPS coordinates * * Requires an API key, which must be provided with the --geocode-api-key parameter * * @param string $siteAddr1 * @param string $siteAddr2 * @param string $siteCity * @param string $siteZip * @param string $siteCountry * * @return array - The geocodeAddress location */ function geocodeAddress(string $siteAddr1, string $siteAddr2, string $siteCity, string $siteZip, string $siteCountry) : array { global $verbose, $debug, $quiet, $geocodeApiKey, $httpsProxy; $latGeocode = ''; $lngGeocode = ''; $googleApiUrl = 'https://maps.googleapis.com/maps/api/geocode/json'; if (!$geocodeApiKey) { // Dont even try without the key print 'Error: --geocode-api-key must be given with --geocode-address' . PHP_EOL; display_help(); exit(1); } $requestUrl = sprintf('%s?address=%s,%s,%s,%s&key=%s', $googleApiUrl, urlencode($siteAddr1), urlencode($siteAddr2), urlencode($siteCity), urlencode($siteCountry), $geocodeApiKey); if ($verbose || $debug) { echoQuiet("Geocode URL: $requestUrl\n" . PHP_EOL); } $result = fetchCurl($requestUrl); if ($result) { $jsonResult = json_decode($result); if ($debug) { echoQuiet('Result was: ' . print_r($jsonResult, true)); } if ($jsonResult && isset($jsonResult->results[0])) { $latGeocode = $jsonResult->results[0]->geometry->location->lat; $lngGeocode = $jsonResult->results[0]->geometry->location->lng; if (!$quiet) { echoQuiet("Geocoded Coordinates: $latGeocode,$lngGeocode\n" . PHP_EOL); } } else { if (!$quiet) { echoQuiet("Error: Query to URL: $requestUrl failed.\n" . PHP_EOL); } } } return ([$latGeocode, $lngGeocode]); } function fixCoordinates(string $lat, string $lng) : array { $utfCoord = mb_convert_encoding("$lat $lng", 'ISO-8859-1', 'UTF-8'); // Normalise the characters to put them through a regex if (preg_match('/(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([NS]) ' . '+(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([EW])/', $utfCoord, $matches)) { array_shift($matches); // Get rid of $matches[0] [$degN, $minN, $secN, $NS, $degE, $minE, $secE, $EW] = $matches; // Get the matches from the regex $degN = (float) $degN; $minN = (float) $minN; $secN = (float) $secN; $degE = (float) $degE; $minE = (float) $minE; $secE = (float) $secE; $lat = sprintf('%0.6f', ($NS == 'S' ? -1 : 1) * ($degN + ($minN / 60) + ($secN / 3600))); $lng = sprintf('%0.6f', ($EW == 'W' ? -1 : 1) * ($degE + ($minE / 60) + ($secE / 3600))); } return ([$lat, $lng]); } function echoQuiet(string $str, int $level = 0) : void { global $quiet, $log; if (!$quiet) { print("$str"); } if ($log) { $str = preg_replace('/^[\n| ]?+/', '', $str); cacti_log($str, false, 'ADD_SITE:', $level); } } function fetchCurl(string $url) : string|false { global $verbose, $debug, $httpsProxy; if (!function_exists('curl_init')) { print 'Error: cURL must be enabled in PHP if --geocode is specified.' . PHP_EOL . 'See http://php.net/manual/en/curl.setup.php for help.' . PHP_EOL; display_help(); exit(1); } $curl = curl_init(); $header[] = 'Accept: text/xml,application/xml,application/json,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'; $header[] = 'Cache-Control: max-age=0'; $header[] = 'Connection: keep-alive'; $header[] = 'Keep-Alive: 300'; $header[] = 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7'; $header[] = 'Accept-Language: en-us,en;q=0.5'; curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_TIMEOUT, 10); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, false); if ($httpsProxy) { if ($verbose || $debug) { echoQuiet("Using HTTPS proxy: $httpsProxy" . PHP_EOL); } curl_setopt($curl, CURLOPT_PROXY, $httpsProxy); } $buffer = curl_exec($curl); if (!is_string($buffer)) { $error = curl_error($curl); echoQuiet('Error: cURL request failed: ' . $error . PHP_EOL); return false; } return $buffer; } /** * display_version - displays version information * * @return void */ function display_version() : void { $version = get_cacti_cli_version(); echoQuiet("Cacti Add Site Utility, Version $version, " . COPYRIGHT_YEARS . PHP_EOL); } /** * display_help - displays help information * * @return void */ function display_help() : void { global $log; $log = false; display_version(); echoQuiet(PHP_EOL); echoQuiet('Usage: add_site.php [site-options] [--quiet]' . PHP_EOL . PHP_EOL); echoQuiet('Site options:' . PHP_EOL); echoQuiet(" --name=[Site Name] e.g. 'Telehouse East'" . PHP_EOL); echoQuiet(" --addr1=[Address Line 1] e.g. 'Coriander Road'" . PHP_EOL); echoQuiet(" --addr2=[Address Line 2] e.g. 'Poplar'" . PHP_EOL); echoQuiet(" --city=[City] e.g. 'London''" . PHP_EOL); echoQuiet(" --state=[State] e.g. 'London'" . PHP_EOL); echoQuiet(" --postcode=[Zip or Postcode] e.g. 'E14 2AA'" . PHP_EOL); echoQuiet(" --country=[Country] e.g. 'United Kingdom'" . PHP_EOL); echoQuiet(" --timezone=[Timezone] e.g. 'Europe/London'" . PHP_EOL); echoQuiet(" --latitude=[Latitutude] e.g. '51.5115172'" . PHP_EOL); echoQuiet(" --longitude=[Longitude] e.g. '-0.0017868'" . PHP_EOL); echoQuiet(" --alt-name=[Alt. Name] e.g. 'LINX Telehouse'" . PHP_EOL); echoQuiet(" --notes=[Site Notes] e.g. 'Email: support@telehouse.net'" . PHP_EOL . PHP_EOL); echoQuiet('Geocoding Options:' . PHP_EOL); echoQuiet(' --geocode Try to turn addresses into GPS coordinates' . PHP_EOL); echoQuiet((' --geocode-api-key Your Google API key - ' . 'https://developers.google.com/maps/documentation/geocoding/get-api-key') . PHP_EOL); echoQuiet((' --proxy Proxy server to use in ' . 'http://proxy.server:port format') . PHP_EOL . PHP_EOL); echoQuiet('Device Map Options:' . PHP_EOL); echoQuiet(" --device-map-regex=[regular expression] e.g.'rtr-th[e|w]-pe\d'" . PHP_EOL); echoQuiet(" --device-map-wildcard=[mysql like] e.g.'rtr-%the%-pe%'" . PHP_EOL); echoQuiet(" --ip-map-regex=[regular expression] e.g. '172.31.224.[1-8]'" . PHP_EOL); echoQuiet(" --ip-map-wildcard=[mysql like] e.g.'172.31.224.%'" . PHP_EOL); echoQuiet(' --do-map Do the mapping.' . PHP_EOL . PHP_EOL); echoQuiet('General Options:' . PHP_EOL); echoQuiet(' --quiet Keep it quiet' . PHP_EOL); echoQuiet(' --no-replace Allow duplicate site names to be created' . PHP_EOL . PHP_EOL); echoQuiet('Notes:' . PHP_EOL); echoQuiet(' By default, sites with the same name will be updated rather than added.' . PHP_EOL); echoQuiet(' This can be disabled with --no-replace' . PHP_EOL . PHP_EOL); echoQuiet(' GPS coordinates should preferably be in dotted decimal format,' . PHP_EOL); echoQuiet(' if supplied in DMS format, a conversion will be attempted, but' . PHP_EOL); echoQuiet(' your mileage may vary.' . PHP_EOL . PHP_EOL); echoQuiet(' Devices can be mapped to the site by providing either regular expression' . PHP_EOL); echoQuiet(' or MySQL wildcard against the host description or IP address.' . PHP_EOL . PHP_EOL); echoQuiet(' By default, only matching devices will be shown, to actually make' . PHP_EOL); echoQuiet(' the changes, use the --do-map option. This is to mistaken updates,' . PHP_EOL); echoQuiet(' please check your filters work first!' . PHP_EOL . PHP_EOL); echoQuiet(' There are some macros which will be expanded in the --notes field:' . PHP_EOL . PHP_EOL); echoQuiet(' %DATE% - The current date in mysql format' . PHP_EOL); echoQuiet(' %TIME% - The current time in mysql format' . PHP_EOL); echoQuiet(' %GOOGLE_MAPS_URL% - The link to Google Maps for this sites GPS coordinates' . PHP_EOL . PHP_EOL); exit; }