123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- <?php
- #-
- # Copyright (c) 2011-2015 Joe Clarke <jclarke@cisco.com>
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions
- # are met:
- # 1. Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- #
- # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- # SUCH DAMAGE.
- #
- #
- include_once '../db.inc.php';
- include_once 'swreg.inc.php';
- include_once '../swreg_creds.inc.php';
- require_once 'MDB2.php';
- require_once 'Log.php';
- $dsn = "mysql://$db_user:$db_pass@$db_host/$db_name";
- $options = array('result_buffering', false);
- $dbh = MDB2::factory($dsn, $options);
- if (PEAR::isError($dbh)) {
- die($dbh->getMessage());
- }
- $dbh->setFetchMode(MDB2_FETCHMODE_ASSOC);
- $logger = Log::singleton('file', LOGFILE, TOOL_NAME . ' : Switch Registrar');
- if ($logger === FALSE) {
- die("Failed to open logfile.\n");
- }
- $mask = Log::UPTO(LOG_LEVEL);
- $logger->setMask($mask);
- $pid = $_GET['pid'];
- $sn = $_GET['sn'];
- $version = $_GET['version'];
- $num_ports = $_GET['num_ports'];
- header('Content-type: text/plain');
- if (!isset($pid) || !isset($sn) || !isset($version) || !isset($num_ports)) {
- echo "ERROR: Invalid request!\r\n";
- $logger->emerg("Invalid request from " . $_SERVER['REMOTE_ADDR'] . " pid = '$pid', sn = '$sn', version = '$version', num_ports = '$num_ports'");
- exit(1);
- }
- $logger->debug("Received request from $sn: pid = $pid, version = $version, num_ports = $num_ports");
- $image = NULL;
- $config = NULL;
- $found_pid = NULL;
- $not_configed = "ERROR: Tool not properly configured.\r\n";
- foreach ($ZTP_PIDS as $zpid) {
- if (preg_match("/$zpid/", $pid)) {
- if (!isset($IMG_VERS[$zpid])) {
- echo $not_configed;
- $logger->emerg("\$IMG_VERS[$zpid] is not defined in swreg.inc.php!");
- exit(1);
- }
- if ($version != $IMG_VERS[$zpid]) {
- if (!isset($IMG_FILES[$zpid])) {
- echo $not_configed;
- $logger->emerg("\$IMG_FILES[$zpid] is not defined in swreg.inc.php!");
- exit(1);
- }
- $image = $IMG_FILES[$zpid];
- }
- if (!isset($EEM_CONFIG_FILES[$zpid])) {
- echo $not_configed;
- $logger->emerg("\$EEM_CONFIG_FILES[$zpid] is not defined in swreg.inc.php!");
- exit(1);
- }
- $eem_tmpl = $EEM_CONFIG_FILES[$zpid];
- if (!isset($START_PORTS[$zpid])) {
- echo $not_configed;
- $logger->emerg("\$START_PORTS[$zpid] is not defined in swreg.inc.php!");
- exit(1);
- }
- $start_port = $START_PORTS[$zpid];
- if (!isset($PORT_TYPES[$zpid])) {
- echo $not_configed;
- $logger->emerg("\$PORT_TYPES[$zpid] is not defined in swreg.inc.php!");
- exit(1);
- }
- $port_type = $PORT_TYPES[$zpid];
- $found_pid = $zpid;
- }
- }
- if ($found_pid === NULL) {
- $logger->crit("Request from unknown PID: $pid");
- echo "ERROR: Unknown PID: $pid\r\n";
- exit(1);
- }
- $sql = 'SELECT assigned_switch, max_ports, checked_out FROM DEVICE_MAP WHERE serial_number = ?';
- $sth = $dbh->prepare($sql);
- if (PEAR::isError($sth)) {
- echo "ERROR: Failed to prepare query '$sql': " . $sth->getUserInfo() . "\r\n";
- $logger->crit("Failed to prepare query '$sql': " . $sth->getUserInfo());
- exit(1);
- }
- $res = $sth->execute(array($sn));
- $sth->free();
- if (PEAR::isError($res)) {
- echo "ERROR: Failed to execute query '$sql' with parameter '$sn': " . $res->getUserInfo() . "\r\n";
- $logger->crit("Failed to execute query '$sql' with parameter '$sn': " . $res->getUserInfo());
- exit(1);
- }
- $row = $res->fetchRow();
- $max_ports = $row['max_ports'];
- if ($row['checked_out'] == 0) {
- echo "ERROR: Switch has not yet been provisioned via the web\r\n";
- $logger->crit("Switch $sn ({$_SERVER['REMOTE_ADDR']}) has not yet been provisioned via the web");
- exit(1);
- }
- if ($max_ports > $num_ports) {
- echo "ERROR: Switch has been provisioned for $max_ports but this physical switch only has $num_ports\r\n";
- $logger->crit("Switch $sn has been provisioned for $max_ports but this physical switch only has $num_ports");
- exit(1);
- }
- $sql = 'SELECT s.name AS hostname, s.location AS snmp_loc, s.is_idf AS is_idf, a.address AS ip, a.router AS gw, a.mask AS mask, a.mgmt_vlan AS mgmt_vlan, a.location AS location FROM SWITCHES s, ADDRESSES a WHERE s.name = ? AND s.ip_address = a.address';
- $sth = $dbh->prepare($sql);
- if (PEAR::isError($sth)) {
- echo "ERROR: Failed to prepare query '$sql': " . $sth->getUserInfo() . "\r\n";
- $logger->crit("Failed to prepare query '$sql': " . $sth->getUserInfo());
- exit(1);
- }
- $res = $sth->execute(array($row['assigned_switch']));
- $sth->free();
- if (PEAR::isError($res)) {
- echo "ERROR: Failed to execute query '$sql' with parameter '{$row['assigned_switch']}': " . $res->getUserInfo() . "\r\n";
- $logger->crit("Failed to execute query '$sql' with parameter '{$row['assigned_switch']}': " . $res->getUserInfo());
- exit(1);
- }
- $row = $res->fetchRow();
- $port_contents = "interface range {$port_type}{$start_port} - $max_ports\n";
- if (file_exists(PORT_TMPL_DIR . '/devices/' . $row['hostname'] . '-ports.tmpl')) {
- $port_contents = file_get_contents(PORT_TMPL_DIR . '/devices/' . $row['hostname'] . '-ports.tmpl');
- } else {
- if (file_exists(PORT_TMPL_DIR . '/ports.tmpl')) {
- $port_contents .= file_get_contents(PORT_TMPL_DIR . '/ports.tmpl');
- }
- if (file_exists(PORT_TMPL_DIR . '/' . $found_pid . '/ports.tmpl')) {
- $port_contents .= file_get_contents(PORT_TMPL_DIR . '/' . $found_pid . '/ports.tmpl');
- }
- if (file_exists(PORT_TMPL_DIR . '/DYNAMIC/ports.tmpl')) {
- $port_contents .= file_get_contents(PORT_TMPL_DIR . '/DYNAMIC/ports.tmpl');
- }
- if (file_exists(PORT_TMPL_DIR . '/DYNAMIC/' . $found_pid . '/ports.tmpl')) {
- $port_contents .= file_get_contents(PORT_TMPL_DIR . '/DYNAMIC/' . $found_pid . '/ports.tmpl');
- }
- }
- $snmp_loc = $row['snmp_loc'];
- if (!$snmp_loc || $snmp_loc == '') {
- $snmp_loc = $row['location'];
- }
- $ew_keywords = preg_replace("/\s/", '_', $snmp_loc);
- $ew_role = 'ACCESS-SWITCH';
- if ($row['is_idf'] == 1) {
- $ew_role = 'IDF-SWITCH';
- }
- $contents = "";
- if (file_exists(DEVICE_TMPL_DIR . "/device.tmpl")) {
- $contents .= file_get_contents(DEVICE_TMPL_DIR . "/device.tmpl");
- }
- if (file_exists(DEVICE_TMPL_DIR . '/' . $found_pid . '/device.tmpl')) {
- $contents .= file_get_contents(DEVICE_TMPL_DIR . '/' . $found_pid . '/device.tmpl');
- }
- if (file_exists(DEVICE_TMPL_DIR . '/actions/actions.tmpl')) {
- $contents .= file_get_contents(DEVICE_TMPL_DIR . '/actions/actions.tmpl');
- }
- if (file_exists(DEVICE_TMPL_DIR . '/actions/' . $found_pid . '/actions.tmpl')) {
- $contents .= file_get_contents(DEVICE_TMPL_DIR . '/actions/' . $found_pid . '/actions.tmpl');
- }
- $contents .= "end\n";
- $contents = str_replace("%%PORT_CONFIG%%", $port_contents, $contents);
- $contents = str_replace("%%MGMT_VLAN%%", $row['mgmt_vlan'], $contents);
- $contents = str_replace("%%HOSTNAME%%", $row['hostname'], $contents);
- $contents = str_replace("%%EW_DOMAIN%%", $row['location'], $contents);
- $contents = str_replace("%%EW_KEYWORDS%%", $ew_keywords, $contents);
- $contents = str_replace("%%EW_ROLE%%", $ew_role, $contents);
- $contents = str_replace("%%VTP_DOMAIN%%", $row['location'], $contents);
- $contents = str_replace("%%MGMT_IP%%", $row['ip'], $contents);
- $contents = str_replace("%%MGMT_MASK%%", $row['mask'], $contents);
- $contents = str_replace("%%MGMT_GW%%", $row['gw'], $contents);
- $contents = str_replace("%%SNMP_LOCATION%%", $snmp_loc, $contents);
- $contents = str_replace("%%START_PORT%%", $start_port, $contents);
- $contents = str_replace("%%MAX_PORT%%", $max_ports, $contents);
- # XXX: TODO
- $contents = str_replace("%%STACK_CONFIG%%", "!", $contents);
- # Replace creds
- $contents = str_replace("%%ADMIN_SECRET%%", ADMIN_SECRET, $contents);
- $contents = str_replace("%%TACACS_KEY%%", TACACS_KEY, $contents);
- $contents = str_replace("%%EW_SHARED_SECRET%%", EW_SHARED_SECRET, $contents);
- $contents = str_replace("%%EW_MGMT_SHARED_SECRET%%", EW_MGMT_SHARED_SECRET, $contents);
- $contents = str_replace("%%SNMPV3_USER%%", SNMPV3_USER, $contents);
- $contents = str_replace("%%SNMPV3_PASS%%", SNMPV3_PASS, $contents);
- $vlan_contents = file_get_contents(VLAN_TMPL_DIR . "/" . strtolower($row['location']) . "-vlan.tmpl");
- $contents = str_replace("%%VLAN_TMPL%%", $vlan_contents, $contents);
- $eem_contents = file_get_contents(TFTPBOOT . '/' . $eem_tmpl);
- $contents = str_replace("%%EEM_CONFIG%%", $eem_contents, $contents);
- if (isset($VLAN_OVERRIDES) && isset($VLAN_OVERRIDES[$row['location']])) {
- foreach ($VLAN_OVERRIDES[$row['location']] as $vn => $vi) {
- $VLANS[$vn] = $vi;
- }
- }
- foreach ($VLANS as $vn => $vi) {
- $vname = strtoupper($vn);
- $vname = str_replace(' ', '_', $vname);
- $macro = '%%' . $vname . '_VLAN%%';
- $contents = str_replace($macro, $vi, $contents);
- }
- $custom_macros = array();
- if (isset($CUSTOM_MACROS)) {
- foreach ($CUSTOM_MACROS as $macro => $mv) {
- $custom_macros[$macro] = $mv;
- }
- }
- if (isset($MDF_OVERRIDES) && isset($MDF_OVERRIDES[$row['location']])) {
- foreach ($MDF_OVERRIDES[$row['locations']] as $macro => $mv) {
- $custom_macros[$macro] = $mv;
- }
- }
- foreach ($custom_macros as $macro => $mv) {
- $contents = str_replace("%%$macro%%", $mv, $contents);
- }
- umask(0022);
- $fd = @fopen(DEVICE_CONFIG_DIR . '/' . $row['hostname'] . "-config.txt", "w");
- fwrite($fd, $contents);
- fclose($fd);
- $fd = @fopen(DEVICE_TMP_DIR . '/' . $row['hostname'] . "-config.txt", "w");
- fclose($fd);
- chmod(DEVICE_TMP_DIR . '/' . $row['hostname'] . "-config.txt", 0666);
- echo "Config: {$row['hostname']}-config.txt\r\n";
- if ($image !== NULL) {
- echo "Image: $image\r\n";
- }
- $logger->info("Successfully provisioned switch $sn ($pid) {$row['hostname']}");
- $dbh->disconnect();
- $logger->close();
- ?>
|