function renderSLBDefConfig() { $defaults = getSLBDefaults(); startPortlet('SLB default configs'); printOpFormIntro('save'); echo '<table cellspacing=0 cellpadding=5 align=center>'; echo '<tr><th class=tdright>VS config</th><td colspan=2><textarea name=vsconfig rows=10 cols=80>' . stringForTextarea($defaults['vsconfig']) . '</textarea></td>'; echo '<td rowspan=2>'; echo '</td></tr>'; echo '<tr><th class=tdright>RS config</th><td colspan=2><textarea name=rsconfig rows=10 cols=80>' . stringForTextarea($defaults['rsconfig']) . '</textarea></td></tr>'; echo '</form></table>'; printImageHREF('SAVE', 'Save changes', TRUE); finishPortlet(); }
function generateSLBConfig2($triplet_list) { $ret = ''; global $parser_class; $gl_parser = new $parser_class(); $defaults = getSLBDefaults(TRUE); $gl_parser->addMacro('GLOBAL_VS_CONF', dos2unix($defaults['vsconfig'])); $gl_parser->addMacro('GLOBAL_RS_CONF', dos2unix($defaults['rsconfig'])); $gl_parser->addMacro('RSPORT', '%VPORT%'); $gl_parser->addMacro('VS_PREPEND', "# LB (id == %LB_ID%): %LB_NAME%\n# VSG (id == %VSG_ID%): %VS_NAME%\n# RS (id == %RSP_ID%): %RSP_NAME%"); // group triplets by object_id, vs_id $grouped = array(); foreach ($triplet_list as $triplet) { $grouped[$triplet['object_id']][$triplet['vs_id']][] = $triplet; } foreach ($grouped as $object_id => $subarr) { $seen_vs_groups = array(); $lb_parser = clone $gl_parser; $lb_cell = spotEntity('object', $object_id); $lb_parser->addMacro('LB_ID', $lb_cell['id']); $lb_parser->addMacro('LB_NAME', $lb_cell['name']); foreach ($subarr as $vs_id => $triplets) { $vs_parser = clone $lb_parser; $vs_cell = spotEntity('ipvs', $vs_id); if (!isset($vs_cell['ports']) || !isset($vs_cell['vips'])) { amplifyCell($vs_cell); } $vs_parser->addMacro('VS_ID', $vs_cell['id']); $vs_parser->addMacro('VSG_ID', $vs_cell['id']); $vs_parser->addMacro('VS_NAME', $vs_cell['name']); $vs_parser->addMacro('VS_RS_CONF', dos2unix($vs_cell['rsconfig'])); foreach ($triplets as $triplet) { $virtual_services = array(); $tr_parser = clone $vs_parser; $rs_cell = spotEntity('ipv4rspool', $triplet['rspool_id']); $tr_parser->addMacro('RSP_ID', $rs_cell['id']); $tr_parser->addMacro('RSP_NAME', $rs_cell['name']); $tr_parser->addMacro('RSP_VS_CONF', dos2unix($rs_cell['vsconfig'])); $tr_parser->addMacro('RSP_RS_CONF', dos2unix($rs_cell['rsconfig'])); $tr_parser->addMacro('VS_VS_CONF', dos2unix($vs_cell['vsconfig'])); // VS-driven vsconfig has higher priority than RSP-driven foreach ($triplet['ports'] as $port_row) { $is_mark = $port_row['proto'] == 'MARK'; $p_parser = clone $tr_parser; $p_parser->addMacro('VS_HEADER', $is_mark ? 'fwmark %MARK%' : '%VIP% %VPORT%'); $p_parser->addMacro('PROTO', $is_mark ? 'TCP' : $port_row['proto']); $p_parser->addMacro($is_mark ? 'MARK' : 'VPORT', $port_row['vport']); foreach ($vs_cell['ports'] as $vport) { if ($vport['vport'] == $port_row['vport'] && $vport['proto'] == $port_row['proto']) { $p_parser->addMacro('PORT_VS_CONF', dos2unix($vport['vsconfig'])); $p_parser->addMacro('PORT_RS_CONF', dos2unix($vport['rsconfig'])); break; } } $p_parser->addMacro('SLB_PORT_VS_CONF', dos2unix($port_row['vsconfig'])); $p_parser->addMacro('SLB_PORT_RS_CONF', dos2unix($port_row['rsconfig'])); if ($is_mark) { $p_parser->addMacro('RS_HEADER', '%RSIP%'); // find enabled IP families to fill IP_VER $seen_families = array(); foreach ($triplet['vips'] as $ip_row) { $family_length = strlen($ip_row['vip']); $seen_families[$family_length] = $family_length == 16 ? 6 : 4; } if (!$seen_families) { $seen_families['unknown'] = ''; } foreach ($seen_families as $ip_ver) { $fam_parser = clone $p_parser; if ($ip_ver) { $fam_parser->addMacro('IP_VER', $ip_ver); } if ('' != ($vs_config = generateVSSection($fam_parser))) { $virtual_services["IPv{$ip_ver} " . $fam_parser->expandMacro('VS_HEADER')] = $vs_config; } } } else { $p_parser->addMacro('RS_HEADER', '%RSIP% %RSPORT%'); foreach ($triplet['vips'] as $ip_row) { $ip_parser = clone $p_parser; $ip_parser->addMacro('VIP', ip_format($ip_row['vip'])); $ip_parser->addMacro('IP_VER', strlen($ip_row['vip']) == 16 ? 6 : 4); $ip_parser->addMacro('PRIO', $ip_row['prio']); foreach ($vs_cell['vips'] as $vip) { if ($vip['vip'] === $ip_row['vip']) { $ip_parser->addMacro('VIP_VS_CONF', dos2unix($vip['vsconfig'])); $ip_parser->addMacro('VIP_RS_CONF', dos2unix($vip['rsconfig'])); break; } } $ip_parser->addMacro('SLB_VIP_VS_CONF', dos2unix($ip_row['vsconfig'])); $ip_parser->addMacro('SLB_VIP_RS_CONF', dos2unix($ip_row['rsconfig'])); if ('' != ($vs_config = generateVSSection($ip_parser))) { $virtual_services[$port_row['proto'] . " " . $ip_parser->expandMacro('VS_HEADER')] = $vs_config; } } // vips } } //ports // group multiple virtual_services into vs_groups $groups = array(); foreach ($virtual_services as $key => $content) { $groups[$content][] = preg_replace('/^(TCP|UDP|IPv[46]?)\\s+/', '', $key); } foreach ($groups as $content => $keys) { if (NULL !== ($new_content = callHook('generateSLBConfig_stage2', $content, $keys))) { $content = $new_content; } $ret .= $tr_parser->expand("\n%VS_PREPEND%\n"); if (count($keys) == 1) { $ret .= "virtual_server " . array_first($keys) . " {\n" . $content . "}\n"; } else { // come up with the name for new VS group $vsg_name = makeUniqueVSGName($seen_vs_groups, $keys, $vs_cell); $seen_vs_groups[$vsg_name] = 1; $tr_parser->addMacro('VSG_NAME', $vsg_name); $ret .= $tr_parser->expand("virtual_server_group %VSG_NAME% {\n"); foreach ($keys as $vs_header) { $ret .= "\t{$vs_header}\n"; } $ret .= "}\n"; $ret .= $tr_parser->expand("virtual_server group %VSG_NAME% {\n"); $ret .= $content . "}\n"; } } } // triplets } // vs } // balancers return $ret; }
function generateSLBConfig($triplet_list) { $ret = ''; global $parser_class; $gl_parser = new $parser_class(); $defaults = getSLBDefaults(TRUE); $gl_parser->addMacro('GLOBAL_VS_CONF', dos2unix($defaults['vsconfig'])); $gl_parser->addMacro('GLOBAL_RS_CONF', dos2unix($defaults['rsconfig'])); $gl_parser->addMacro('RSPORT', '%VPORT%'); $gl_parser->addMacro('VS_PREPEND', "# LB (id == %LB_ID%): %LB_NAME%\n# VS (id == %VS_ID%): %VS_NAME%\n# RS (id == %RSP_ID%): %RSP_NAME%"); // group triplets by object_id, vs_id $grouped = array(); foreach ($triplet_list as $triplet) { $grouped[$triplet->lb['id']][$triplet->vs['id']][] = $triplet; } foreach ($grouped as $object_id => $subarr) { $lb = array_first(array_first($subarr))->lb; $lb_parser = clone $gl_parser; $lb_parser->addMacro('LB_ID', $lb['id']); $lb_parser->addMacro('LB_NAME', $lb['name']); foreach ($subarr as $vs_id => $triplets) { $vs = array_first($triplets)->vs; $vs_parser = clone $lb_parser; $vs_parser->addMacro('VS_ID', $vs['id']); $vs_parser->addMacro('VS_NAME', $vs['name']); $vs_parser->addMacro('VIP', $vs['vip']); $vs_parser->addMacro('VPORT', $vs['vport']); $vs_parser->addMacro('IP_VER', strlen($vs['vip_bin']) == 16 ? 6 : 4); if ($vs['proto'] == 'MARK') { $vs_parser->addMacro('PROTO', 'TCP'); $mark = implode('', unpack('N', substr($vs['vip_bin'], 0, 4))); $vs_parser->addMacro('MARK', $mark); $vs_parser->addMacro('VS_HEADER', "fwmark {$mark}"); } else { $vs_parser->addMacro('VS_HEADER', $vs['vip'] . ' ' . $vs['vport']); $vs_parser->addMacro('PROTO', $vs['proto']); } $vs_parser->addMacro('VS_RS_CONF', dos2unix($vs['rsconfig'])); $vip_bin = ip_checkparse($vs_parser->expandMacro('VIP')); if ($vip_bin === FALSE) { $family_length = 4; } else { $family_length = strlen($vip_bin); } foreach ($triplets as $triplet) { $rsp = $triplet->rs; $rs_parser = clone $vs_parser; $rs_parser->addMacro('RSP_ID', $rsp['id']); $rs_parser->addMacro('RSP_NAME', $rsp['name']); $rs_parser->addMacro('RSP_VS_CONF', dos2unix($rsp['vsconfig'])); $rs_parser->addMacro('RSP_RS_CONF', dos2unix($rsp['rsconfig'])); $rs_parser->addMacro('VS_VS_CONF', dos2unix($vs['vsconfig'])); // VS-driven vsconfig has higher priority than RSP-driven $rs_parser->addMacro('PRIO', $triplet->slb['prio']); $rs_parser->addMacro('SLB_VS_CONF', dos2unix($triplet->slb['vsconfig'])); $rs_parser->addMacro('SLB_RS_CONF', dos2unix($triplet->slb['rsconfig'])); $ret .= $rs_parser->expand("\n%VS_PREPEND%\nvirtual_server %VS_HEADER% {\n\tprotocol %PROTO%\n\t%GLOBAL_VS_CONF%\n\t%RSP_VS_CONF%\n\t%VS_VS_CONF%\n\t%SLB_VS_CONF%\n"); foreach ($rs_parser->getRSList() as $rs_row) { if ($rs_row['inservice'] != 'yes') { continue; } $parser = clone $rs_parser; $parser->addMacro('RS_HEADER', $parser->expandMacro('PROTO') == 'MARK' ? '%RSIP%' : '%RSIP% %RSPORT%'); $parser->addMacro('RSIP', $rs_row['rsip']); if (isset($rs_row['rsport'])) { $parser->addMacro('RSPORT', $rs_row['rsport']); } $parser->addMacro('RS_COMMENT', $rs_row['comment']); $parser->addMacro('RS_RS_CONF', dos2unix($rs_row['rsconfig'])); // do not add v6 reals into v4 service and vice versa $rsip_bin = ip_checkparse($parser->expandMacro('RSIP')); if ($rsip_bin !== FALSE && strlen($rsip_bin) == $family_length) { foreach (explode(',', $parser->expandMacro('RSPORT')) as $rsp_token) { $port_range = explode('-', $rsp_token); if (count($port_range) < 1) { throw new InvalidArgException('RSPORT', $rsp_token, "invalid RS port range"); } if (count($port_range) < 2) { $port_range[] = $port_range[0]; } if ($port_range[0] > $port_range[1]) { throw new InvalidArgException('RSPORT', $rsp_token, "invalid RS port range"); } for ($rsport = $port_range[0]; $rsport <= $port_range[1]; $rsport++) { $r_parser = clone $parser; $r_parser->addMacro('RSPORT', $rsport); $ret .= $r_parser->expand("\n\t%RS_PREPEND%\n\treal_server %RS_HEADER% {\n\t\t%GLOBAL_RS_CONF%\n\t\t%VS_RS_CONF%\n\t\t%RSP_RS_CONF%\n\t\t%SLB_RS_CONF%\n\t\t%RS_RS_CONF%\n\t}\n"); } } } } $ret .= "}\n"; } } } return $ret; }
public function prepareParserForRS(&$parser, $rs_row) { $parser->addMacro('RS_HEADER', $this->vs['proto'] == 'MARK' ? '%RSIP%' : '%RSIP% %RSPORT%'); $parser->addMacro('RSIP', $rs_row['rsip']); $parser->addMacro('RSPORT', isset($rs_row['rsport']) ? $rs_row['rsport'] : $this->vs['vport']); // VS port is a default value for RS port $parser->addMacro('RS_COMMENT', $rs_row['comment']); $defaults = getSLBDefaults(TRUE); $parser->addMacro('GLOBAL_RS_CONF', dos2unix($defaults['rs'])); $parser->addMacro('VS_RS_CONF', dos2unix($this->vs['rsconfig'])); $parser->addMacro('RSP_RS_CONF', dos2unix($this->rs['rsconfig'])); $parser->addMacro('SLB_RS_CONF', dos2unix($this->slb['rsconfig'])); $parser->addMacro('RS_RS_CONF', $rs_row['rsconfig']); }
function generateConfig() { // fill the predefined macros $parser = $this->createParser(); $parser->addMacro('LB_ID', $this->lb['id']); $parser->addMacro('LB_NAME', $this->lb['name']); $parser->addMacro('VS_ID', $this->vs['id']); $parser->addMacro('VS_NAME', $this->vs['name']); $parser->addMacro('RSP_ID', $this->rs['id']); $parser->addMacro('RSP_NAME', $this->rs['name']); $parser->addMacro('VIP', $this->vs['vip']); $parser->addMacro('VPORT', $this->vs['vport']); $parser->addMacro('PRIO', $this->slb['prio']); $parser->addMacro('IP_VER', strlen($this->vs['vip_bin']) == 16 ? 6 : 4); if ($this->vs['proto'] == 'MARK') { $parser->addMacro('PROTO', 'TCP'); $mark = implode('', unpack('N', substr($this->vs['vip_bin'], 0, 4))); $parser->addMacro('MARK', $mark); $parser->addMacro('VS_HEADER', "fwmark {$mark}"); } else { $parser->addMacro('VS_HEADER', $this->vs['vip'] . ' ' . $this->vs['vport']); $parser->addMacro('PROTO', $this->vs['proto']); } $defaults = getSLBDefaults(TRUE); $parser->addMacro('GLOBAL_VS_CONF', dos2unix($defaults['vs'])); $parser->addMacro('RSP_VS_CONF', dos2unix($this->rs['vsconfig'])); $parser->addMacro('VS_VS_CONF', dos2unix($this->vs['vsconfig'])); $parser->addMacro('SLB_VS_CONF', dos2unix($this->slb['vsconfig'])); // return the expanded VS template using prepared $macros array $ret = $parser->expand("\n# LB (id == %LB_ID%): %LB_NAME%\n# VS (id == %VS_ID%): %VS_NAME%\n# RS (id == %RSP_ID%): %RSP_NAME%\nvirtual_server %VS_HEADER% {\n\tprotocol %PROTO%\n\t%GLOBAL_VS_CONF%\n\t%RSP_VS_CONF%\n\t%VS_VS_CONF%\n\t%SLB_VS_CONF%\n"); foreach (getRSListInPool($this->rs['id']) as $rs) { // do not add v6 reals into v4 service and vice versa if (strlen($rs['rsip_bin']) != strlen($this->vs['vip_bin'])) { continue; } if ($rs['inservice'] != 'yes') { continue; } $parser->pushdefs(); // backup macros $parser->addMacro('RS_HEADER', $this->vs['proto'] == 'MARK' ? '%RSIP%' : '%RSIP% %RSPORT%'); $parser->addMacro('RSIP', $rs['rsip']); $parser->addMacro('RSPORT', isset($rs['rsport']) ? $rs['rsport'] : $this->vs['vport']); // VS port is a default value for RS port $parser->addMacro('RS_COMMENT', $rs['comment']); $parser->addMacro('GLOBAL_RS_CONF', dos2unix($defaults['rs'])); $parser->addMacro('VS_RS_CONF', dos2unix($this->vs['rsconfig'])); $parser->addMacro('RSP_RS_CONF', dos2unix($this->rs['rsconfig'])); $parser->addMacro('SLB_RS_CONF', dos2unix($this->slb['rsconfig'])); $parser->addMacro('RS_RS_CONF', $rs['rsconfig']); $ret .= $parser->expand("\n\t%RS_PREPEND%\n\treal_server %RS_HEADER% {\n\t\t%GLOBAL_RS_CONF%\n\t\t%VS_RS_CONF%\n\t\t%RSP_RS_CONF%\n\t\t%SLB_RS_CONF%\n\t\t%RS_RS_CONF%\n\t}\n"); $parser->popdefs(); // restore original (VS-driven) macros } $ret .= "}\n"; return $ret; }