├── documentation ├── usgtool.mwb └── usgtool.mwb.bak ├── includes ├── php │ ├── mysqli.php │ ├── settings.php.template │ ├── top.php │ ├── bottom.php │ └── functions.php ├── css │ └── footer.css └── js │ └── vizjs │ └── viz.js ├── update.sql ├── actions ├── generate │ ├── configparts │ │ ├── interfaces.php │ │ ├── firewall.php │ │ ├── vpn.php │ │ ├── services.php │ │ └── protocols.php │ ├── graph.js.php │ └── config.php ├── remove │ ├── network.php │ └── unifitounifi.php ├── get │ ├── config.php │ ├── networkconfig.php │ └── siteconfig.php ├── add │ └── unifitounifi.php ├── update │ ├── networkconfig.php │ └── siteconfig.php └── readcontrollerdata.php ├── README.md ├── index.php └── db.sql /documentation/usgtool.mwb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florisvdk/unifi-json-tool/HEAD/documentation/usgtool.mwb -------------------------------------------------------------------------------- /documentation/usgtool.mwb.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/florisvdk/unifi-json-tool/HEAD/documentation/usgtool.mwb.bak -------------------------------------------------------------------------------- /includes/php/mysqli.php: -------------------------------------------------------------------------------- 1 | connect_error) { 4 | exit("There was an error with your connection: ".$dbhandle->connect_error); 5 | } 6 | $dbhandle->set_charset('utf8mb4'); 7 | ?> -------------------------------------------------------------------------------- /update.sql: -------------------------------------------------------------------------------- 1 | -- MySQL Workbench Synchronization 2 | -- Generated: 2019-01-30 11:39 3 | -- Model: New Model 4 | -- Version: 1.0 5 | -- Project: Name of the project 6 | -- Author: Floris 7 | 8 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 9 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 10 | SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; 11 | 12 | ALTER TABLE `sitesubnets` 13 | ADD COLUMN `mdnsrepeater` TINYINT(1) NULL DEFAULT NULL AFTER `dnsredirect`; 14 | 15 | 16 | SET SQL_MODE=@OLD_SQL_MODE; 17 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 18 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 19 | -------------------------------------------------------------------------------- /actions/generate/configparts/interfaces.php: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /includes/css/footer.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer styles 2 | -------------------------------------------------- */ 3 | html { 4 | position: relative; 5 | min-height: 100%; 6 | } 7 | body { 8 | margin-bottom: 60px; /* Margin bottom by footer height */ 9 | } 10 | .footer { 11 | position: absolute; 12 | bottom: 0; 13 | width: 100%; 14 | height: 60px; /* Set the fixed height of the footer here */ 15 | line-height: 60px; /* Vertically center the text there */ 16 | background-color: #f5f5f5; 17 | } 18 | 19 | 20 | /* Custom page CSS 21 | -------------------------------------------------- */ 22 | /* Not required for template or sticky footer method. */ 23 | 24 | .container { 25 | width: auto; 26 | max-width: 680px; 27 | padding: 0 15px; 28 | } -------------------------------------------------------------------------------- /includes/php/settings.php.template: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /actions/generate/graph.js.php: -------------------------------------------------------------------------------- 1 | "' . $vpnconnection['site2'] . '" [arrowhead=none]; '; 18 | 19 | } 20 | 21 | 22 | ?> 23 | var viz = new Viz(); 24 | 25 | viz.renderSVGElement('digraph { }') 26 | .then(function(element) { 27 | document.getElementById("vpndiagram").appendChild(element); 28 | }) 29 | .catch(error => { 30 | // Create a new Viz instance (@see Caveats page for more info) 31 | viz = new Viz(); 32 | 33 | // Possibly display the error 34 | console.error(error); 35 | }); 36 | 39 | -------------------------------------------------------------------------------- /actions/remove/network.php: -------------------------------------------------------------------------------- 1 | '; 18 | exit; 19 | 20 | } 21 | 22 | $strQuery1 = "DELETE FROM `sitesubnets` WHERE `idsitesubnets`='" . $network . "';"; 23 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 24 | 25 | echo ''; 26 | echo ''; 27 | 28 | // geef footer weer 29 | 30 | include("../../includes/php/bottom.php"); 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /includes/php/top.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | UniFi config.gateway.json tool 7 | 8 | 9 | 10 | 11 | 12 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # configtool 2 | 3 | This tool imports unifi site information using the Art-of-WiFi/UniFi-API-client and makes it easier to do some advanced configuration. 4 | 5 | # Possible in the latest version: 6 | 7 | - Import information form unifi controller 8 | - Add a unifi site to other unifi site vpn with bgp for routing with generated passwords 9 | - IGMP proxy configuration 10 | - Display the generated json only, you can copy and paste this into the correct file on the controller. Api to automate this is planned. 11 | - Mdns repeater 12 | 13 | More is in development. 14 | 15 | # Installation: 16 | 17 | 1. install an apache or nginx webserver with php 5.6 or higher. 18 | 2. install a mysql or mariadb server and the php module for it. 19 | 3. copy or move the settings template in includes/php/ to settings.php in the same folder and edit the configuration. 20 | 4. Import the db.sql file in the root directory. 21 | 5. Done. 22 | 23 | # Upgrading 24 | 25 | 1. Replace all files. 26 | 2. Import the update.sql file in the root directory. 27 | 3. Done. 28 | -------------------------------------------------------------------------------- /actions/remove/unifitounifi.php: -------------------------------------------------------------------------------- 1 | '; 18 | exit; 19 | 20 | } 21 | 22 | $strQuery1 = "DELETE FROM `vpnconnectionsunifi` WHERE `idvpnconnections`='" . $vpnconnection . "';"; 23 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 24 | 25 | echo ''; 26 | echo ''; 27 | 28 | // geef footer weer 29 | 30 | include("../../includes/php/bottom.php"); 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /includes/php/bottom.php: -------------------------------------------------------------------------------- 1 |
2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /actions/generate/config.php: -------------------------------------------------------------------------------- 1 | '; 16 | exit; 17 | 18 | } 19 | 20 | // get site info 21 | 22 | $siteinfo = getsiteinfo($site); 23 | $configbgprouterid = $siteinfo['bgprouterid']; 24 | $configbgpas = $siteinfo['bgpas']; 25 | 26 | // get site features and add them to variables for later use 27 | 28 | if (hasbgp($site)) $configvpnarray = getvpnconnectioninfo($site); 29 | if (hasdnsredirect($site)) $configdnsarray = getdnsredirectinfo($site); 30 | 31 | // start generating config 32 | 33 | $configurationjson .= '{'; 34 | 35 | // firewall is first 36 | 37 | include('configparts/firewall.php'); 38 | 39 | // interfaces is seccond 40 | 41 | include('configparts/interfaces.php'); 42 | 43 | // protocols is third 44 | 45 | include('configparts/protocols.php'); 46 | 47 | // services 48 | 49 | include('configparts/services.php'); 50 | 51 | // vpn 52 | 53 | include('configparts/vpn.php'); 54 | 55 | $configurationjson .= ' 56 | } 57 | '; 58 | 59 | ?> 60 | -------------------------------------------------------------------------------- /actions/generate/configparts/firewall.php: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /actions/get/config.php: -------------------------------------------------------------------------------- 1 | '; 17 | exit; 18 | 19 | } 20 | 21 | // get site info 22 | 23 | $siteinfo = getsiteinfo($site); 24 | $configbgprouterid = $siteinfo['bgprouterid']; 25 | $configbgpas = $siteinfo['bgpas']; 26 | 27 | // get site features and add them to variables for later use 28 | 29 | echo "

"; 30 | 31 | if (hasigmpproxy($site)) echo "This site uses igmp proxy.
"; 32 | if (hasbgp($site)) echo "This site uses bgp.
"; 33 | if (hasdnsredirect($site)) echo "This site uses dns redirect.
"; 34 | if (hasmdnsrepeater($site)) echo "This site uses mdns repeater.
"; 35 | 36 | if (hasbgp($site)) $configvpnarray = getvpnconnectioninfo($site); 37 | if (hasdnsredirect($site)) $configdnsarray = getdnsredirectinfo($site); 38 | 39 | echo "

"; 40 | 41 | // get generated config 42 | 43 | include('../generate/config.php'); 44 | 45 | echo '
';
46 | 
47 | echo htmlspecialchars($configurationjson, ENT_QUOTES);
48 | 
49 | echo '
'; 50 | 51 | // geef footer weer 52 | 53 | include("../../includes/php/bottom.php"); 54 | 55 | ?> 56 | -------------------------------------------------------------------------------- /actions/add/unifitounifi.php: -------------------------------------------------------------------------------- 1 | '; 19 | exit; 20 | 21 | } 22 | 23 | $strQuery1 = "SELECT idvpnconnections FROM vpnconnectionsunifi WHERE (site1 = '" . $site1 . "' AND site2 = '" . $site2 . "') or (site1 = '" . $site2 . "' AND site2 = '" . $site1 . "') ;"; 24 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 25 | $response1 = mysqli_fetch_array($result1); 26 | 27 | if ($response1 == Null) { 28 | 29 | // generate secret 30 | 31 | $secret = generatePassword(20); 32 | 33 | $strQuery1 = "INSERT INTO `vpnconnectionsunifi` (`site1`, `site2`, `secret`) VALUES ('" . $site1 . "', '" . $site2 . "', '" . $secret . "');"; 34 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 35 | 36 | } 37 | 38 | echo ''; 39 | echo ''; 40 | 41 | // geef footer weer 42 | 43 | include("../../includes/php/bottom.php"); 44 | 45 | ?> 46 | -------------------------------------------------------------------------------- /actions/update/networkconfig.php: -------------------------------------------------------------------------------- 1 | '; 19 | exit; 20 | 21 | } 22 | 23 | if ($_POST['bgp'] == 1) { 24 | 25 | $bgp = 1; 26 | 27 | } else { 28 | 29 | $bgp = 0; 30 | 31 | } 32 | 33 | if ($_POST['igmpupstream'] == 1) { 34 | 35 | $igmpupstream = 1; 36 | 37 | } else { 38 | 39 | $igmpupstream = 0; 40 | 41 | } 42 | 43 | if ($_POST['igmpdownstream'] == 1) { 44 | 45 | $igmpdownstream = 1; 46 | 47 | } else { 48 | 49 | $igmpdownstream = 0; 50 | 51 | } 52 | 53 | if ($_POST['dnsredirect'] == 1) { 54 | 55 | $dnsredirect = 1; 56 | 57 | } else { 58 | 59 | $dnsredirect = 0; 60 | 61 | } 62 | 63 | if ($_POST['mdnsrepeater'] == 1) { 64 | 65 | $mdnsrepeater = 1; 66 | 67 | } else { 68 | 69 | $mdnsrepeater = 0; 70 | 71 | } 72 | 73 | $strQuery1 = "UPDATE `sitesubnets` SET `inbgp`='" . $bgp . "', `igmpupstream`='" . $igmpupstream . "', `igmpdownstream`='" . $igmpdownstream . "', `dnsredirect`='" . $dnsredirect . "', `mdnsrepeater`='" . $mdnsrepeater . "' WHERE `idsitesubnets`='" . $network . "';"; 74 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 75 | 76 | echo ''; 77 | echo ''; 78 | 79 | // display footer 80 | 81 | include("../../includes/php/bottom.php"); 82 | 83 | ?> 84 | -------------------------------------------------------------------------------- /actions/update/siteconfig.php: -------------------------------------------------------------------------------- 1 | '; 18 | exit; 19 | 20 | } 21 | 22 | // first do bgp 23 | 24 | if ($_POST['bgp'] == 1) { 25 | 26 | $bgp = 1; 27 | 28 | } else { 29 | 30 | $bgp = 0; 31 | 32 | } 33 | 34 | $bgprouterid = filter_var($_POST['bgprouterid'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); 35 | $bgpas = filter_var($_POST['bgpas'], FILTER_VALIDATE_INT); 36 | if ($bgpas == false) $bgpas = 0; 37 | 38 | $strQuery1 = "UPDATE `sites` SET `bgp`='" . $bgp . "', `bgprouterid`='" . $bgprouterid . "', `bgpas`='" . $bgpas . "' WHERE `idsites`='" . $site . "';"; 39 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 40 | 41 | // then igmp 42 | 43 | if ($_POST['igmp'] == 1) { 44 | 45 | $igmp = 1; 46 | $igmpupstreamaltsubnet = '0.0.0.0/0'; 47 | 48 | } else { 49 | 50 | $igmp = 0; 51 | $igmpupstreamaltsubnet = ''; 52 | 53 | } 54 | 55 | $strQuery1 = "UPDATE `sites` SET `igmpupstream`='" . $igmp . "', `igmpupstreamaltsubnet`='" . $igmpupstreamaltsubnet . "' WHERE `idsites`='" . $site . "';"; 56 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 57 | 58 | // then dns 59 | 60 | if ($_POST['dnsredirect'] == 1) { 61 | 62 | $dnsredirect = 1; 63 | $dnsredirectip = '0.0.0.0/0'; 64 | 65 | } else { 66 | 67 | $dnsredirect = 0; 68 | 69 | } 70 | 71 | $dnsredirectip = filter_var($_POST['dnsredirectip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); 72 | 73 | $dnsridirectinterface = mysqli_real_escape_string($dbhandle, $_POST['dnsridirectinterface']); 74 | 75 | $strQuery1 = "UPDATE `sites` SET `dnsredirect`='" . $dnsredirect . "', `dnsredirectip`='" . $dnsredirectip . "', `dnsridirectinterface`='" . $dnsridirectinterface . "' WHERE `idsites`='" . $site . "';"; 76 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 77 | 78 | echo ''; 79 | echo ''; 80 | 81 | // display footer 82 | 83 | include("../../includes/php/bottom.php"); 84 | 85 | ?> 86 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | Read controller data'; 9 | 10 | echo '

'; 11 | 12 | echo '
Vpn diagram

'; 13 | 14 | // add new unifi to unifi vpn 15 | 16 | echo '
Add unifi to unifi vpn tunnel
'; 17 | 18 | echo '

'; 35 | 36 | // show generated config 37 | 38 | echo '
Show configuration
'; 39 | 40 | echo '

'; 49 | 50 | // edit a site config 51 | 52 | echo '
Edit site configuration
'; 53 | 54 | echo '

'; 63 | 64 | $customjs = ''; 65 | 66 | include('includes/php/bottom.php'); 67 | 68 | ?> 69 | -------------------------------------------------------------------------------- /actions/get/networkconfig.php: -------------------------------------------------------------------------------- 1 | '; 19 | exit; 20 | 21 | } 22 | 23 | $siteinfo = getsiteinfofull($site); 24 | $networkinfo = getnetworkinfofull($network); 25 | 26 | 27 | // site name and network title 28 | 29 | echo '

' . $siteinfo['name'] . ': ' . $networkinfo['name'] . '

'; 30 | 31 | // edit network settings 32 | 33 | echo '
Network settings
'; 34 | 35 | echo ''; 36 | echo ''; 37 | 38 | echo '
'; 47 | 48 | echo '
'; 57 | 58 | echo '
'; 67 | 68 | echo '
'; 77 | 78 | echo '
'; 87 | 88 | echo '
'; 89 | 90 | echo '

'; 91 | 92 | 93 | // display footer 94 | 95 | include("../../includes/php/bottom.php"); 96 | 97 | ?> 98 | -------------------------------------------------------------------------------- /actions/generate/configparts/vpn.php: -------------------------------------------------------------------------------- 1 | 76 | -------------------------------------------------------------------------------- /actions/generate/configparts/services.php: -------------------------------------------------------------------------------- 1 | 103 | -------------------------------------------------------------------------------- /actions/generate/configparts/protocols.php: -------------------------------------------------------------------------------- 1 | 134 | -------------------------------------------------------------------------------- /db.sql: -------------------------------------------------------------------------------- 1 | -- MySQL Workbench Synchronization 2 | -- Generated: 2019-01-30 11:36 3 | -- Model: New Model 4 | -- Version: 1.0 5 | -- Project: Name of the project 6 | -- Author: Floris 7 | 8 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 9 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 10 | SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; 11 | 12 | CREATE TABLE IF NOT EXISTS `sites` ( 13 | `idsites` INT(11) NOT NULL AUTO_INCREMENT, 14 | `name` TEXT NULL DEFAULT NULL, 15 | `unifiid` TEXT NULL DEFAULT NULL, 16 | `usg` TINYINT(1) NULL DEFAULT NULL, 17 | `wan1` TEXT NULL DEFAULT NULL, 18 | `wan1interface` TEXT NULL DEFAULT NULL, 19 | `wan2` TEXT NULL DEFAULT NULL, 20 | `wan2interface` TEXT NULL DEFAULT NULL, 21 | `bgp` TINYINT(1) NULL DEFAULT NULL, 22 | `bgprouterid` TEXT NULL DEFAULT NULL, 23 | `bgpas` INT(11) NULL DEFAULT NULL, 24 | `igmpupstream` TINYINT(1) NULL DEFAULT NULL, 25 | `igmpupstreamaltsubnet` TEXT NULL DEFAULT NULL, 26 | `dnsredirect` TINYINT(1) NULL DEFAULT NULL, 27 | `dnsredirectip` TEXT NULL DEFAULT NULL, 28 | `dnsridirectinterface` TEXT NULL DEFAULT NULL, 29 | PRIMARY KEY (`idsites`), 30 | UNIQUE INDEX `idsites_UNIQUE` (`idsites` ASC)) 31 | ENGINE = InnoDB 32 | DEFAULT CHARACTER SET = utf8; 33 | 34 | CREATE TABLE IF NOT EXISTS `vpnsitesother` ( 35 | `idvpnsitesother` INT(11) NOT NULL AUTO_INCREMENT, 36 | `bgprouterid` TEXT NULL DEFAULT NULL, 37 | `bgpas` INT(11) NULL DEFAULT NULL, 38 | `secret` TEXT NULL DEFAULT NULL, 39 | PRIMARY KEY (`idvpnsitesother`), 40 | UNIQUE INDEX `idvpnsitesother_UNIQUE` (`idvpnsitesother` ASC)) 41 | ENGINE = InnoDB 42 | DEFAULT CHARACTER SET = utf8; 43 | 44 | CREATE TABLE IF NOT EXISTS `vpnconnectionsunifi` ( 45 | `idvpnconnections` INT(11) NOT NULL AUTO_INCREMENT, 46 | `site1` INT(11) NOT NULL, 47 | `site2` INT(11) NOT NULL, 48 | `secret` TEXT NULL DEFAULT NULL, 49 | PRIMARY KEY (`idvpnconnections`), 50 | UNIQUE INDEX `idvpnconnections_UNIQUE` (`idvpnconnections` ASC), 51 | INDEX `fk_vpnconnectionsunifi_sites_idx` (`site1` ASC), 52 | INDEX `fk_vpnconnectionsunifi_sites1_idx` (`site2` ASC), 53 | CONSTRAINT `fk_vpnconnectionsunifi_sites` 54 | FOREIGN KEY (`site1`) 55 | REFERENCES `sites` (`idsites`) 56 | ON DELETE NO ACTION 57 | ON UPDATE NO ACTION, 58 | CONSTRAINT `fk_vpnconnectionsunifi_sites1` 59 | FOREIGN KEY (`site2`) 60 | REFERENCES `sites` (`idsites`) 61 | ON DELETE NO ACTION 62 | ON UPDATE NO ACTION) 63 | ENGINE = InnoDB 64 | DEFAULT CHARACTER SET = utf8; 65 | 66 | CREATE TABLE IF NOT EXISTS `vpnconnectionsother` ( 67 | `idvpnconnectionsother` INT(11) NOT NULL AUTO_INCREMENT, 68 | `site1` INT(11) NOT NULL, 69 | `site2` INT(11) NOT NULL, 70 | PRIMARY KEY (`idvpnconnectionsother`), 71 | UNIQUE INDEX `idvpnconnectionsother_UNIQUE` (`idvpnconnectionsother` ASC), 72 | INDEX `fk_vpnconnectionsother_sites1_idx` (`site1` ASC), 73 | INDEX `fk_vpnconnectionsother_vpnsitesother1_idx` (`site2` ASC), 74 | CONSTRAINT `fk_vpnconnectionsother_sites1` 75 | FOREIGN KEY (`site1`) 76 | REFERENCES `sites` (`idsites`) 77 | ON DELETE NO ACTION 78 | ON UPDATE NO ACTION, 79 | CONSTRAINT `fk_vpnconnectionsother_vpnsitesother1` 80 | FOREIGN KEY (`site2`) 81 | REFERENCES `vpnsitesother` (`idvpnsitesother`) 82 | ON DELETE NO ACTION 83 | ON UPDATE NO ACTION) 84 | ENGINE = InnoDB 85 | DEFAULT CHARACTER SET = utf8; 86 | 87 | CREATE TABLE IF NOT EXISTS `sitesubnets` ( 88 | `idsitesubnets` INT(11) NOT NULL AUTO_INCREMENT, 89 | `name` TEXT NULL DEFAULT NULL, 90 | `subnet` TEXT NULL DEFAULT NULL, 91 | `inbgp` TINYINT(1) NULL DEFAULT NULL, 92 | `site` INT(11) NOT NULL, 93 | `interface` TEXT NULL DEFAULT NULL, 94 | `igmpupstream` TINYINT(1) NULL DEFAULT NULL, 95 | `igmpdownstream` TINYINT(1) NULL DEFAULT NULL, 96 | `dnsredirect` TINYINT(1) NULL DEFAULT NULL, 97 | `mdnsrepeater` TINYINT(1) NULL DEFAULT NULL, 98 | PRIMARY KEY (`idsitesubnets`), 99 | UNIQUE INDEX `idsitesubnets_UNIQUE` (`idsitesubnets` ASC), 100 | INDEX `fk_sitesubnets_sites1_idx` (`site` ASC), 101 | CONSTRAINT `fk_sitesubnets_sites1` 102 | FOREIGN KEY (`site`) 103 | REFERENCES `sites` (`idsites`) 104 | ON DELETE NO ACTION 105 | ON UPDATE NO ACTION) 106 | ENGINE = InnoDB 107 | DEFAULT CHARACTER SET = utf8; 108 | 109 | 110 | SET SQL_MODE=@OLD_SQL_MODE; 111 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 112 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; -------------------------------------------------------------------------------- /actions/get/siteconfig.php: -------------------------------------------------------------------------------- 1 | '; 18 | exit; 19 | 20 | } 21 | 22 | $siteinfo = getsiteinfofull($site); 23 | 24 | // site name title 25 | 26 | echo '

' . $siteinfo['name'] . '

'; 27 | 28 | // show vpn connections 29 | 30 | echo '
Vpn tunnels
'; 31 | 32 | foreach (getvpnconnectioninfo($site) as &$vpnconnections) { 33 | 34 | echo ''; 35 | 36 | } 37 | 38 | echo '
To site
' . $vpnconnections['remotename'] . '

'; 39 | 40 | // show netwoks 41 | 42 | echo '
Site networks
'; 43 | 44 | foreach (getsitenetworks($site) as &$sitesubnets) { 45 | 46 | echo ''; 98 | 99 | } 100 | 101 | echo '
To siteDistribute in bgpIGMPDNS redirectmDNS repeater
47 | 48 | 49 |
' . $sitesubnets['subnet'] . ''; 50 | 51 | if ($sitesubnets['inbgp'] == 1 ) { 52 | 53 | echo ''; 54 | 55 | } else { 56 | 57 | echo ''; 58 | 59 | } 60 | 61 | echo ''; 62 | 63 | if ($sitesubnets['igmpupstream'] == 1 or $sitesubnets['igmpdownstream'] == 1) { 64 | 65 | echo ''; 66 | 67 | } else { 68 | 69 | echo ''; 70 | 71 | } 72 | 73 | echo ''; 74 | 75 | if ($sitesubnets['dnsredirect'] == 1) { 76 | 77 | echo ''; 78 | 79 | } else { 80 | 81 | echo ''; 82 | 83 | } 84 | 85 | echo ''; 86 | 87 | if ($sitesubnets['mdnsrepeater'] == 1) { 88 | 89 | echo ''; 90 | 91 | } else { 92 | 93 | echo ''; 94 | 95 | } 96 | 97 | echo '

'; 102 | 103 | // edit site settings 104 | 105 | echo '
Site settings
'; 106 | 107 | echo ''; 108 | 109 | echo '
bgp router id:
'; 118 | 119 | echo '
bgp as:
'; 120 | 121 | echo '
'; 122 | 123 | echo '

'; 132 | 133 | echo '
'; 142 | 143 | echo '
dns redirect ip:
'; 144 | 145 | echo '
'; 162 | 163 | echo '
'; 164 | 165 | echo '

'; 166 | 167 | // display footer 168 | 169 | include("../../includes/php/bottom.php"); 170 | 171 | ?> 172 | -------------------------------------------------------------------------------- /actions/readcontrollerdata.php: -------------------------------------------------------------------------------- 1 | set_debug($debug); 15 | $loginresults = $unifi_connection->login(); 16 | 17 | // get client and device info 18 | 19 | $sites_array = $unifi_connection->list_sites(); 20 | 21 | // loop trugh sites 22 | 23 | echo'
'; 24 | 25 | foreach ($sites_array as $site) { 26 | 27 | $usg = 0; 28 | $wanip = '0.0.0.0'; 29 | $wanip2 = '0.0.0.0'; 30 | 31 | $wanint = ''; 32 | $wan2int = ''; 33 | $lanint = ''; 34 | $lan2int = ''; 35 | 36 | // get devices and check for usg 37 | 38 | $unifi_connection2 = new UniFi_API\Client($controlleruser, $controllerpassword, $controllerurl, $site->name, $controllerversion); 39 | $set_debug_mode2 = $unifi_connection2->set_debug($debug); 40 | $loginresults2 = $unifi_connection2->login(); 41 | 42 | $devices_array = $unifi_connection2->list_devices(); 43 | 44 | foreach ($devices_array as $device) { 45 | 46 | if ($device->model == 'UGW3' or $device->model == 'UGW4'or $device->model == 'UGWXG') { 47 | 48 | $usg = 1; 49 | 50 | $ports_array = $device->port_table; 51 | 52 | foreach ($ports_array as $port) { 53 | 54 | if ($port->name == "wan") { 55 | 56 | $wanip = $port->ip; 57 | $wanint = $port->ifname; 58 | 59 | } 60 | 61 | if ($port->name == "wan2") { 62 | 63 | $wanip2 = $port->ip; 64 | $wan2int = $port->ifname; 65 | 66 | } 67 | 68 | if ($port->name == "lan") { 69 | 70 | $lanint = $port->ifname; 71 | 72 | } 73 | 74 | if ($port->name == "lan2") { 75 | 76 | $lan2int = $port->ifname; 77 | 78 | } 79 | 80 | } 81 | 82 | } 83 | 84 | } 85 | 86 | // insert into db 87 | 88 | $strQuery1 = "SELECT idsites FROM sites WHERE unifiid = '" . $site->name . "' ;"; 89 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 90 | $response1 = mysqli_fetch_array($result1); 91 | 92 | if ($response1 == Null) { 93 | 94 | $strQuery1 = "INSERT INTO `sites` (`name`, `unifiid`, `usg`, `wan1`, `wan2`, `wan1interface`, `wan2interface`) 95 | VALUES ('" . $site->desc . "', '" . $site->name . "', '" . $usg . "', '" . $wanip . "', '" . $wanip2 . "', '" . $wanint . "', '" . $wan2int . "');"; 96 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 97 | 98 | } else { 99 | 100 | $strQuery1 = "UPDATE `sites` SET `usg`='" . $usg . "', `wan1`='" . $wanip . "', `wan2`='" . $wanip2 . "', `wan1interface`='" . $wanint . "', `wan2interface`='" . $wan2int . "' WHERE `unifiid`='" . $site->name . "';"; 101 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 102 | 103 | } 104 | 105 | //display site info 106 | 107 | echo '
'; 108 | echo '
Site data
'; 109 | echo 'Site name: ' . $site->desc . '
'; 110 | echo 'Site id: ' . $site->name . '
'; 111 | echo 'Site has usg: ' . $usg . '
'; 112 | echo 'Wan ip: ' . $wanip . '
'; 113 | echo 'Wan interface: ' . $wanint . '
'; 114 | echo 'Wan2 ip: ' . $wanip2 . '
'; 115 | echo 'Wan2 interface: ' . $wan2int . '
'; 116 | echo 'Lan interface: ' . $lanint . '
'; 117 | echo 'Lan2 interface: ' . $lan2int . '
'; 118 | 119 | $strQuery1 = "SELECT idsites FROM sites WHERE unifiid = '" . $site->name . "' ;"; 120 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 121 | $response1 = mysqli_fetch_array($result1); 122 | 123 | $siteid = $response1['idsites']; 124 | 125 | // loop trugh networks 126 | 127 | $networks_array = $unifi_connection2->list_networkconf(); 128 | 129 | foreach ($networks_array as $network) { 130 | 131 | if ($network->vlan == null) { 132 | 133 | if ($network->networkgroup == 'LAN') { 134 | 135 | $networkinterface = $lanint; 136 | 137 | } else { 138 | 139 | $networkinterface = $lan2int; 140 | 141 | } 142 | 143 | } else { 144 | 145 | if ($network->networkgroup == 'LAN') { 146 | 147 | $networkinterface = $lanint . "." . $network->vlan; 148 | 149 | } else { 150 | 151 | $networkinterface = $lan2int . "." . $network->vlan; 152 | 153 | } 154 | 155 | } 156 | 157 | $strQuery1 = "SELECT idsitesubnets FROM sitesubnets WHERE site = '" . $siteid . "' AND subnet = '" . calculateunifinetworkadress($network->ip_subnet) . "';"; 158 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 159 | $response1 = mysqli_fetch_array($result1); 160 | 161 | // this is realy hackey and needs to be fixed 162 | 163 | if ($response1 == Null) { 164 | 165 | if ($network->ip_subnet != NULL) { 166 | 167 | $strQuery1 = "INSERT INTO `sitesubnets` (`subnet`, `inbgp`, `site`, `igmpupstream`, `igmpdownstream`, `dnsredirect`, `name`, `interface`) 168 | VALUES ('" . calculateunifinetworkadress($network->ip_subnet) . "', '0', '" . $siteid . "', '0', '0', '0', '" . $network->name . "', '" . $networkinterface . "');"; 169 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 170 | 171 | } 172 | 173 | } else { 174 | 175 | $strQuery1 = "UPDATE `sitesubnets` SET `interface`='" . $networkinterface . "', `name`='" . $network->name . "' WHERE site = '" . $siteid . "' AND subnet = '" . calculateunifinetworkadress($network->ip_subnet) . "';"; 176 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 177 | 178 | } 179 | 180 | } 181 | 182 | echo '

'; 183 | 184 | } 185 | 186 | echo'
'; 187 | 188 | include('../includes/php/bottom.php'); 189 | 190 | ?> 191 | -------------------------------------------------------------------------------- /includes/php/functions.php: -------------------------------------------------------------------------------- 1 | query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 11 | 12 | $response1 = mysqli_fetch_array($result1); 13 | 14 | return $response1; 15 | 16 | } 17 | 18 | // getvpnconnectioninfo - returns an array with all the given site to site vpn info 19 | 20 | function getvpnconnectioninfo($site) { 21 | 22 | global $dbhandle; 23 | 24 | $strQuery1 = "SELECT sites.wan1 AS localwan, sites.bgprouterid AS localrouterid, sites.bgpas AS localas, vpnconnectionsunifi.secret, sites_1.wan1 AS remotewan, sites_1.bgprouterid AS remoterouterid, sites_1.bgpas AS remoteas, sites_1.name AS remotename, vpnconnectionsunifi.idvpnconnections 25 | FROM sites AS sites_1 INNER JOIN (sites INNER JOIN vpnconnectionsunifi ON sites.idsites = vpnconnectionsunifi.site1) ON sites_1.idsites = vpnconnectionsunifi.site2 WHERE vpnconnectionsunifi.site1 = '" . $site . "';"; 26 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 27 | 28 | while ($row = mysqli_fetch_array($result1)) { 29 | 30 | $array[] = $row; 31 | 32 | } 33 | 34 | $strQuery1 = "SELECT sites_1.wan1 AS localwan, sites_1.bgprouterid AS localrouterid, sites_1.bgpas AS localas, vpnconnectionsunifi.secret, sites.wan1 AS remotewan, sites.bgprouterid AS remoterouterid, sites.bgpas AS remoteas, sites.name AS remotename, vpnconnectionsunifi.idvpnconnections 35 | FROM sites AS sites_1 INNER JOIN (sites INNER JOIN vpnconnectionsunifi ON sites.idsites = vpnconnectionsunifi.site1) ON sites_1.idsites = vpnconnectionsunifi.site2 WHERE vpnconnectionsunifi.site2 = '" . $site . "';"; 36 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 37 | 38 | while ($row = mysqli_fetch_array($result1)) { 39 | 40 | $array[] = $row; 41 | 42 | } 43 | 44 | return $array; 45 | 46 | } 47 | 48 | // getsiteswithusg - returns an array with all the sites with usg 49 | 50 | function getsiteswithusg() { 51 | 52 | global $dbhandle; 53 | 54 | $strQuery1 = "SELECT idsites, name FROM sites WHERE usg = '1';"; 55 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 56 | 57 | while ($row = mysqli_fetch_array($result1)) { 58 | 59 | $array[] = $row; 60 | 61 | } 62 | 63 | return $array; 64 | 65 | } 66 | 67 | // getvpnconnections - returns an array with all the vpn connections 68 | 69 | function getvpnconnectionsforgraph() { 70 | 71 | global $dbhandle; 72 | 73 | $strQuery1 = "SELECT sites.name AS site1, sites_1.name AS site2 74 | FROM (vpnconnectionsunifi INNER JOIN sites ON vpnconnectionsunifi.site1 = sites.idsites) INNER JOIN sites AS sites_1 ON vpnconnectionsunifi.site2 = sites_1.idsites;"; 75 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 76 | 77 | while ($row = mysqli_fetch_array($result1)) { 78 | 79 | $array[] = $row; 80 | 81 | } 82 | 83 | return $array; 84 | 85 | } 86 | 87 | // hasigmpproxy - returns true if igmpproxy is used for the site 88 | 89 | function hasigmpproxy($site) { 90 | 91 | global $dbhandle; 92 | 93 | $strQuery1 = "SELECT idsites FROM sites WHERE igmpupstream = '1' AND idsites = '" . $site . "' ;"; 94 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 95 | $response1 = mysqli_fetch_array($result1); 96 | 97 | if($response1 != null) { 98 | 99 | return TRUE; 100 | 101 | } else { 102 | 103 | return FALSE; 104 | 105 | } 106 | 107 | } 108 | 109 | // hasbgp - returns true if bgp is used for the site 110 | 111 | function hasbgp($site) { 112 | 113 | global $dbhandle; 114 | 115 | $strQuery1 = "SELECT idsites FROM sites WHERE bgp = '1' AND idsites = '" . $site . "' ;"; 116 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 117 | $response1 = mysqli_fetch_array($result1); 118 | 119 | if($response1 != null) { 120 | 121 | return TRUE; 122 | 123 | } 124 | 125 | $strQuery1 = "SELECT site FROM sitesubnets WHERE site = '" . $site . "' AND ( igmpupstream = '1' OR igmpupstream = '1' ) ;"; 126 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 127 | $response1 = mysqli_fetch_array($result1); 128 | 129 | if($response1 != null) { 130 | 131 | return TRUE; 132 | 133 | } 134 | 135 | return FALSE; 136 | 137 | } 138 | 139 | // hasmdnsrepeater - returns true if mdns repeater is used for the site 140 | 141 | function hasmdnsrepeater($site) { 142 | 143 | global $dbhandle; 144 | 145 | $strQuery1 = "SELECT site FROM sitesubnets WHERE site = '" . $site . "' AND mdnsrepeater = '1' ;"; 146 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 147 | $response1 = mysqli_fetch_array($result1); 148 | 149 | if($response1 != null) { 150 | 151 | return TRUE; 152 | 153 | } 154 | 155 | return FALSE; 156 | 157 | } 158 | 159 | // hasdnsredirect - returns true if dns redirect is used for the site 160 | 161 | function hasdnsredirect($site) { 162 | 163 | global $dbhandle; 164 | 165 | $strQuery1 = "SELECT idsites FROM sites WHERE dnsredirect = '1' AND idsites = '" . $site . "' ;"; 166 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 167 | $response1 = mysqli_fetch_array($result1); 168 | 169 | if($response1 != null) { 170 | 171 | return TRUE; 172 | 173 | } else { 174 | 175 | return FALSE; 176 | 177 | } 178 | 179 | } 180 | 181 | // getigmpproxyupstream - returns an array with all the needed info 182 | 183 | function getigmpproxyupstream($site) { 184 | 185 | global $dbhandle; 186 | 187 | $strQuery1 = "SELECT wan1interface AS interface, igmpupstreamaltsubnet AS altsubnet FROM sites WHERE igmpupstream = '1' AND idsites = '" . $site . "';"; 188 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 189 | 190 | $response1 = mysqli_fetch_array($result1); 191 | 192 | if ($response1 != Null) { 193 | 194 | return $response1; 195 | 196 | } 197 | 198 | $strQuery1 = "SELECT interface AS interface, subnet AS altsubnet FROM sitesubnets WHERE igmpupstream = '1' AND site = '" . $site . "';"; 199 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 200 | 201 | $response1 = mysqli_fetch_array($result1); 202 | 203 | if ($response1 != Null) { 204 | 205 | return $response1; 206 | 207 | } 208 | 209 | return FALSE; 210 | 211 | } 212 | 213 | // getigmpproxydownstream - returns an array with all the igmpproxy downstream info 214 | 215 | function getigmpproxydownstream($site) { 216 | 217 | global $dbhandle; 218 | 219 | $strQuery1 = "SELECT interface, subnet AS altsubnet 220 | FROM sitesubnets WHERE site = '" . $site . "';"; 221 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 222 | 223 | while ($row = mysqli_fetch_array($result1)) { 224 | 225 | $array[] = $row; 226 | 227 | } 228 | 229 | return $array; 230 | 231 | } 232 | 233 | // getdnsredirect - returns an array with all the needed info 234 | 235 | function getdnsredirectinfo($site) { 236 | 237 | global $dbhandle; 238 | 239 | $strQuery2 = "SELECT interface FROM sitesubnets WHERE dnsredirect = '1' AND site = '" . $site . "';"; 240 | $result2 = $dbhandle->query($strQuery2) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 241 | 242 | while ($row = mysqli_fetch_array($result2)) { 243 | 244 | $array[] = $row; 245 | 246 | } 247 | 248 | return $array; 249 | 250 | } 251 | 252 | // getmdnsrepeaterinfo - returns an array with all the needed info 253 | 254 | function getmdnsrepeaterinfo($site) { 255 | 256 | global $dbhandle; 257 | 258 | $strQuery2 = "SELECT interface FROM sitesubnets WHERE mdnsrepeater = '1' AND site = '" . $site . "';"; 259 | $result2 = $dbhandle->query($strQuery2) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 260 | 261 | while ($row = mysqli_fetch_array($result2)) { 262 | 263 | $array[] = $row; 264 | 265 | } 266 | 267 | return $array; 268 | 269 | } 270 | 271 | // getdnsredirectinfosite - returns an array with all the needed info 272 | 273 | function getdnsredirectinfosite($site) { 274 | 275 | global $dbhandle; 276 | 277 | $strQuery2 = "SELECT dnsridirectinterface, dnsredirectip FROM sites WHERE dnsredirect = '1' AND idsites = '" . $site . "';"; 278 | $result2 = $dbhandle->query($strQuery2) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 279 | $response2 = mysqli_fetch_array($result2); 280 | 281 | return $response2; 282 | 283 | } 284 | 285 | // getsitenetworks - returns an array with all the networks a site has 286 | 287 | function getsitenetworks($site) { 288 | 289 | global $dbhandle; 290 | 291 | $strQuery1 = "SELECT * FROM sitesubnets WHERE site = '" . $site . "';"; 292 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 293 | 294 | while ($row = mysqli_fetch_array($result1)) { 295 | 296 | $array[] = $row; 297 | 298 | } 299 | 300 | return $array; 301 | 302 | } 303 | 304 | // getsiteinfofull - returns an array with all the given site info 305 | 306 | function getsiteinfofull($site) { 307 | 308 | global $dbhandle; 309 | 310 | $strQuery1 = "SELECT * FROM sites WHERE idsites = '" . $site . "';"; 311 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 312 | 313 | $response1 = mysqli_fetch_array($result1); 314 | 315 | return $response1; 316 | 317 | } 318 | 319 | // getnetworkinfofull - returns an array with all the given site info 320 | 321 | function getnetworkinfofull($network) { 322 | 323 | global $dbhandle; 324 | 325 | $strQuery1 = "SELECT * FROM sitesubnets WHERE idsitesubnets = '" . $network . "';"; 326 | $result1 = $dbhandle->query($strQuery1) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}"); 327 | 328 | $response1 = mysqli_fetch_array($result1); 329 | 330 | return $response1; 331 | 332 | } 333 | 334 | // calculateunifinetworkadress - returns an sting in the correct format giveen from the givven ipadressa and subnet 335 | 336 | function calculateunifinetworkadress($ipadressfull) { 337 | 338 | $ipadress = strtok( $ipadressfull, '/' ); 339 | $shortnetmask = strtok( '' ); 340 | 341 | $longnetmask = long2ip(-1 << (32 - (int)$shortnetmask)); 342 | 343 | 344 | $input = new stdClass(); 345 | $input->ip = $ipadress; 346 | $input->netmask = $longnetmask; 347 | $input->ip_int = ip2long($input->ip); 348 | $input->netmask_int = ip2long($input->netmask); 349 | // Network is a logical AND between the address and netmask 350 | $input->network_int = $input->ip_int & $input->netmask_int; 351 | $input->network = long2ip($input->network_int); 352 | 353 | return $input->network . '/' . $shortnetmask; 354 | 355 | } 356 | 357 | // getRandomBytes - get seure random bytes 358 | 359 | function getRandomBytes($nbBytes = 32) { 360 | 361 | $bytes = openssl_random_pseudo_bytes($nbBytes, $strong); 362 | 363 | if (false !== $bytes && true === $strong) { 364 | 365 | return $bytes; 366 | 367 | } else { 368 | 369 | throw new \Exception("Unable to generate secure token from OpenSSL."); 370 | 371 | } 372 | 373 | } 374 | 375 | // generatePassword - generte a secure pawwsord with the provided length 376 | 377 | function generatePassword($length) { 378 | 379 | return substr(preg_replace("/[^a-zA-Z0-9]/", "", base64_encode(getRandomBytes($length+1))),0,$length); 380 | 381 | } 382 | 383 | ?> 384 | -------------------------------------------------------------------------------- /includes/js/vizjs/viz.js: -------------------------------------------------------------------------------- 1 | /* 2 | Viz.js 2.1.2 (Graphviz 2.40.1, Expat 2.2.5, Emscripten 1.37.36) 3 | Copyright (c) 2014-2018 Michael Daines 4 | Licensed under MIT license 5 | 6 | This distribution contains other software in object code form: 7 | 8 | Graphviz 9 | Licensed under Eclipse Public License - v 1.0 10 | http://www.graphviz.org 11 | 12 | Expat 13 | Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper 14 | Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. 15 | Licensed under MIT license 16 | http://www.libexpat.org 17 | 18 | zlib 19 | Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler 20 | http://www.zlib.net/zlib_license.html 21 | */ 22 | (function (global, factory) { 23 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 24 | typeof define === 'function' && define.amd ? define(factory) : 25 | (global.Viz = factory()); 26 | }(this, (function () { 'use strict'; 27 | 28 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 29 | return typeof obj; 30 | } : function (obj) { 31 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 32 | }; 33 | 34 | var classCallCheck = function (instance, Constructor) { 35 | if (!(instance instanceof Constructor)) { 36 | throw new TypeError("Cannot call a class as a function"); 37 | } 38 | }; 39 | 40 | var createClass = function () { 41 | function defineProperties(target, props) { 42 | for (var i = 0; i < props.length; i++) { 43 | var descriptor = props[i]; 44 | descriptor.enumerable = descriptor.enumerable || false; 45 | descriptor.configurable = true; 46 | if ("value" in descriptor) descriptor.writable = true; 47 | Object.defineProperty(target, descriptor.key, descriptor); 48 | } 49 | } 50 | 51 | return function (Constructor, protoProps, staticProps) { 52 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 53 | if (staticProps) defineProperties(Constructor, staticProps); 54 | return Constructor; 55 | }; 56 | }(); 57 | 58 | var _extends = Object.assign || function (target) { 59 | for (var i = 1; i < arguments.length; i++) { 60 | var source = arguments[i]; 61 | 62 | for (var key in source) { 63 | if (Object.prototype.hasOwnProperty.call(source, key)) { 64 | target[key] = source[key]; 65 | } 66 | } 67 | } 68 | 69 | return target; 70 | }; 71 | 72 | var WorkerWrapper = function () { 73 | function WorkerWrapper(worker) { 74 | var _this = this; 75 | 76 | classCallCheck(this, WorkerWrapper); 77 | 78 | this.worker = worker; 79 | this.listeners = []; 80 | this.nextId = 0; 81 | 82 | this.worker.addEventListener('message', function (event) { 83 | var id = event.data.id; 84 | var error = event.data.error; 85 | var result = event.data.result; 86 | 87 | _this.listeners[id](error, result); 88 | delete _this.listeners[id]; 89 | }); 90 | } 91 | 92 | createClass(WorkerWrapper, [{ 93 | key: 'render', 94 | value: function render(src, options) { 95 | var _this2 = this; 96 | 97 | return new Promise(function (resolve, reject) { 98 | var id = _this2.nextId++; 99 | 100 | _this2.listeners[id] = function (error, result) { 101 | if (error) { 102 | reject(new Error(error.message, error.fileName, error.lineNumber)); 103 | return; 104 | } 105 | resolve(result); 106 | }; 107 | 108 | _this2.worker.postMessage({ id: id, src: src, options: options }); 109 | }); 110 | } 111 | }]); 112 | return WorkerWrapper; 113 | }(); 114 | 115 | var ModuleWrapper = function ModuleWrapper(module, render) { 116 | classCallCheck(this, ModuleWrapper); 117 | 118 | var instance = module(); 119 | this.render = function (src, options) { 120 | return new Promise(function (resolve, reject) { 121 | try { 122 | resolve(render(instance, src, options)); 123 | } catch (error) { 124 | reject(error); 125 | } 126 | }); 127 | }; 128 | }; 129 | 130 | // https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding 131 | 132 | 133 | function b64EncodeUnicode(str) { 134 | return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { 135 | return String.fromCharCode('0x' + p1); 136 | })); 137 | } 138 | 139 | function defaultScale() { 140 | if ('devicePixelRatio' in window && window.devicePixelRatio > 1) { 141 | return window.devicePixelRatio; 142 | } else { 143 | return 1; 144 | } 145 | } 146 | 147 | function svgXmlToImageElement(svgXml) { 148 | var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 149 | _ref$scale = _ref.scale, 150 | scale = _ref$scale === undefined ? defaultScale() : _ref$scale, 151 | _ref$mimeType = _ref.mimeType, 152 | mimeType = _ref$mimeType === undefined ? "image/png" : _ref$mimeType, 153 | _ref$quality = _ref.quality, 154 | quality = _ref$quality === undefined ? 1 : _ref$quality; 155 | 156 | return new Promise(function (resolve, reject) { 157 | var svgImage = new Image(); 158 | 159 | svgImage.onload = function () { 160 | var canvas = document.createElement('canvas'); 161 | canvas.width = svgImage.width * scale; 162 | canvas.height = svgImage.height * scale; 163 | 164 | var context = canvas.getContext("2d"); 165 | context.drawImage(svgImage, 0, 0, canvas.width, canvas.height); 166 | 167 | canvas.toBlob(function (blob) { 168 | var image = new Image(); 169 | image.src = URL.createObjectURL(blob); 170 | image.width = svgImage.width; 171 | image.height = svgImage.height; 172 | 173 | resolve(image); 174 | }, mimeType, quality); 175 | }; 176 | 177 | svgImage.onerror = function (e) { 178 | var error; 179 | 180 | if ('error' in e) { 181 | error = e.error; 182 | } else { 183 | error = new Error('Error loading SVG'); 184 | } 185 | 186 | reject(error); 187 | }; 188 | 189 | svgImage.src = 'data:image/svg+xml;base64,' + b64EncodeUnicode(svgXml); 190 | }); 191 | } 192 | 193 | function svgXmlToImageElementFabric(svgXml) { 194 | var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 195 | _ref2$scale = _ref2.scale, 196 | scale = _ref2$scale === undefined ? defaultScale() : _ref2$scale, 197 | _ref2$mimeType = _ref2.mimeType, 198 | mimeType = _ref2$mimeType === undefined ? 'image/png' : _ref2$mimeType, 199 | _ref2$quality = _ref2.quality, 200 | quality = _ref2$quality === undefined ? 1 : _ref2$quality; 201 | 202 | var multiplier = scale; 203 | 204 | var format = void 0; 205 | if (mimeType == 'image/jpeg') { 206 | format = 'jpeg'; 207 | } else if (mimeType == 'image/png') { 208 | format = 'png'; 209 | } 210 | 211 | return new Promise(function (resolve, reject) { 212 | fabric.loadSVGFromString(svgXml, function (objects, options) { 213 | // If there's something wrong with the SVG, Fabric may return an empty array of objects. Graphviz appears to give us at least one element back even given an empty graph, so we will assume an error in this case. 214 | if (objects.length == 0) { 215 | reject(new Error('Error loading SVG with Fabric')); 216 | } 217 | 218 | var element = document.createElement("canvas"); 219 | element.width = options.width; 220 | element.height = options.height; 221 | 222 | var canvas = new fabric.Canvas(element, { enableRetinaScaling: false }); 223 | var obj = fabric.util.groupSVGElements(objects, options); 224 | canvas.add(obj).renderAll(); 225 | 226 | var image = new Image(); 227 | image.src = canvas.toDataURL({ format: format, multiplier: multiplier, quality: quality }); 228 | image.width = options.width; 229 | image.height = options.height; 230 | 231 | resolve(image); 232 | }); 233 | }); 234 | } 235 | 236 | var Viz = function () { 237 | function Viz() { 238 | var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 239 | workerURL = _ref3.workerURL, 240 | worker = _ref3.worker, 241 | Module = _ref3.Module, 242 | render = _ref3.render; 243 | 244 | classCallCheck(this, Viz); 245 | 246 | if (typeof workerURL !== 'undefined') { 247 | this.wrapper = new WorkerWrapper(new Worker(workerURL)); 248 | } else if (typeof worker !== 'undefined') { 249 | this.wrapper = new WorkerWrapper(worker); 250 | } else if (typeof Module !== 'undefined' && typeof render !== 'undefined') { 251 | this.wrapper = new ModuleWrapper(Module, render); 252 | } else if (typeof Viz.Module !== 'undefined' && typeof Viz.render !== 'undefined') { 253 | this.wrapper = new ModuleWrapper(Viz.Module, Viz.render); 254 | } else { 255 | throw new Error('Must specify workerURL or worker option, Module and render options, or include one of full.render.js or lite.render.js after viz.js.'); 256 | } 257 | } 258 | 259 | createClass(Viz, [{ 260 | key: 'renderString', 261 | value: function renderString(src) { 262 | var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 263 | _ref4$format = _ref4.format, 264 | format = _ref4$format === undefined ? 'svg' : _ref4$format, 265 | _ref4$engine = _ref4.engine, 266 | engine = _ref4$engine === undefined ? 'dot' : _ref4$engine, 267 | _ref4$files = _ref4.files, 268 | files = _ref4$files === undefined ? [] : _ref4$files, 269 | _ref4$images = _ref4.images, 270 | images = _ref4$images === undefined ? [] : _ref4$images, 271 | _ref4$yInvert = _ref4.yInvert, 272 | yInvert = _ref4$yInvert === undefined ? false : _ref4$yInvert, 273 | _ref4$nop = _ref4.nop, 274 | nop = _ref4$nop === undefined ? 0 : _ref4$nop; 275 | 276 | for (var i = 0; i < images.length; i++) { 277 | files.push({ 278 | path: images[i].path, 279 | data: '\n\n' 280 | }); 281 | } 282 | 283 | return this.wrapper.render(src, { format: format, engine: engine, files: files, images: images, yInvert: yInvert, nop: nop }); 284 | } 285 | }, { 286 | key: 'renderSVGElement', 287 | value: function renderSVGElement(src) { 288 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 289 | 290 | return this.renderString(src, _extends({}, options, { format: 'svg' })).then(function (str) { 291 | var parser = new DOMParser(); 292 | return parser.parseFromString(str, 'image/svg+xml').documentElement; 293 | }); 294 | } 295 | }, { 296 | key: 'renderImageElement', 297 | value: function renderImageElement(src) { 298 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 299 | var scale = options.scale, 300 | mimeType = options.mimeType, 301 | quality = options.quality; 302 | 303 | 304 | return this.renderString(src, _extends({}, options, { format: 'svg' })).then(function (str) { 305 | if ((typeof fabric === 'undefined' ? 'undefined' : _typeof(fabric)) === "object" && fabric.loadSVGFromString) { 306 | return svgXmlToImageElementFabric(str, { scale: scale, mimeType: mimeType, quality: quality }); 307 | } else { 308 | return svgXmlToImageElement(str, { scale: scale, mimeType: mimeType, quality: quality }); 309 | } 310 | }); 311 | } 312 | }, { 313 | key: 'renderJSONObject', 314 | value: function renderJSONObject(src) { 315 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 316 | var format = options.format; 317 | 318 | 319 | if (format !== 'json' || format !== 'json0') { 320 | format = 'json'; 321 | } 322 | 323 | return this.renderString(src, _extends({}, options, { format: format })).then(function (str) { 324 | return JSON.parse(str); 325 | }); 326 | } 327 | }]); 328 | return Viz; 329 | }(); 330 | 331 | return Viz; 332 | 333 | }))); 334 | --------------------------------------------------------------------------------