list<int> Helper::getAllInterfaceIDs() { Firewall *fw = compiler->fw; list<int> intf_id_list; FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME); for ( ; i!=i.end(); ++i) { Interface *ifs = Interface::cast(*i); assert(ifs); if (ifs->isUnprotected()) continue; // skip! intf_id_list.push_back( (*i)->getId() ); } return intf_id_list; }
void clusterMembersDialog::getPossibleMembers() { t_fwList fwlist; mw->findAllFirewalls(fwlist); Firewall *fw; for (t_fwList::iterator it = fwlist.begin(); it != fwlist.end(); it++) { // does host_OS and platform match? fw = *it; if (fw->getStr("host_OS").c_str() != host_os || fw->getStr("platform").c_str() != platform) { continue; } // does the firewall provide at least one phys. interface? FWObjectTypedChildIterator iface_i = fw->findByType(Interface::TYPENAME); if (iface_i == iface_i.end()) { continue; } else { // previously selected? skip PredFindFw pred; pred.setSearchString(fw->getName().c_str()); t_memberList::iterator it = find_if(selected.begin(), selected.end(), pred); if (it != selected.end()) { continue; } // valid member, add to member list ClusterMember *new_member = createMember(fw); if (new_member == NULL) { qWarning() << "clusterMembersDialog: could not create new " "cluster member"; return; } available.push_back(new_member); } } fwlist.sort(FWObjectNameCmpPredicate()); }
int main(int argc, char** argv) { // The order of initialization of various master components is as follows: // * Validate flags. // * Log build information. // * Libprocess. // * Logging. // * Version process. // * Firewall rules: should be initialized before initializing HTTP endpoints. // * Modules: Load module libraries and manifests before they // can be instantiated. // * Anonymous modules: Later components such as Allocators, and master // contender/detector might depend upon anonymous modules. // * Hooks. // * Allocator. // * Registry storage. // * State. // * Master contendor. // * Master detector. // * Authorizer. // * Slave removal rate limiter. // * `Master` process. // // TODO(avinash): Add more comments discussing the rationale behind for this // particular component ordering. GOOGLE_PROTOBUF_VERIFY_VERSION; master::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on. This cannot be used in conjunction\n" "with `--ip_discovery_command`."); uint16_t port; flags.add(&port, "port", "Port to listen on.", MasterInfo().port()); Option<string> advertise_ip; flags.add(&advertise_ip, "advertise_ip", "IP address advertised to reach this Mesos master.\n" "The master does not bind using this IP address.\n" "However, this IP address may be used to access this master."); Option<string> advertise_port; flags.add(&advertise_port, "advertise_port", "Port advertised to reach Mesos master (along with\n" "`advertise_ip`). The master does not bind to this port.\n" "However, this port (along with `advertise_ip`) may be used to\n" "access this master."); Option<string> zk; flags.add(&zk, "zk", "ZooKeeper URL (used for leader election amongst masters)\n" "May be one of:\n" " `zk://host1:port1,host2:port2,.../path`\n" " `zk://username:password@host1:port1,host2:port2,.../path`\n" " `file:///path/to/file` (where file contains one of the above)\n" "NOTE: Not required if master is run in standalone mode (non-HA)."); // Optional IP discover script that will set the Master IP. // If set, its output is expected to be a valid parseable IP string. Option<string> ip_discovery_command; flags.add(&ip_discovery_command, "ip_discovery_command", "Optional IP discovery binary: if set, it is expected to emit\n" "the IP address which the master will try to bind to.\n" "Cannot be used in conjunction with `--ip`."); Try<flags::Warnings> load = flags.load("MESOS_", argc, argv); if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.version) { cout << "mesos" << " " << MESOS_VERSION << endl; return EXIT_SUCCESS; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } if (ip_discovery_command.isSome() && ip.isSome()) { EXIT(EXIT_FAILURE) << flags.usage( "Only one of `--ip` or `--ip_discovery_command` should be specified"); } if (ip_discovery_command.isSome()) { Try<string> ipAddress = os::shell(ip_discovery_command.get()); if (ipAddress.isError()) { EXIT(EXIT_FAILURE) << ipAddress.error(); } os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get())); } else if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); if (advertise_ip.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get()); } if (advertise_port.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get()); } if (zk.isNone()) { if (flags.master_contender.isSome() ^ flags.master_detector.isSome()) { EXIT(EXIT_FAILURE) << flags.usage("Both --master_contender and --master_detector should " "be specified or omitted."); } } else { if (flags.master_contender.isSome() || flags.master_detector.isSome()) { EXIT(EXIT_FAILURE) << flags.usage("Only one of --zk or the " "--master_contender/--master_detector " "pair should be specified."); } } // Log build information. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } // This should be the first invocation of `process::initialize`. If it returns // `false`, then it has already been called, which means that the // authentication realm for libprocess-level HTTP endpoints was not set to the // correct value for the master. if (!process::initialize( "master", READWRITE_HTTP_AUTHENTICATION_REALM, READONLY_HTTP_AUTHENTICATION_REALM)) { EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the master's " << "`main()` was not the function's first invocation"; } logging::initialize(argv[0], flags, true); // Catch signals. // Log any flag warnings (after logging is initialized). foreach (const flags::Warning& warning, load->warnings) { LOG(WARNING) << warning.message; } spawn(new VersionProcess(), true); // Initialize firewall rules. if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
int main(int argc, char** argv) { // The order of initialization is as follows: // * Windows socket stack. // * Validate flags. // * Log build information. // * Libprocess // * Logging // * Version process // * Firewall rules: should be initialized before initializing HTTP endpoints. // * Modules: Load module libraries and manifests before they // can be instantiated. // * Anonymous modules: Later components such as Allocators, and master // contender/detector might depend upon anonymous modules. // * Hooks. // * Systemd support (if it exists). // * Fetcher and Containerizer. // * Master detector. // * Authorizer. // * Garbage collector. // * Status update manager. // * Resource estimator. // * QoS controller. // * `Agent` process. // // TODO(avinash): Add more comments discussing the rationale behind for this // particular component ordering. #ifdef __WINDOWS__ // Initialize the Windows socket stack. process::Winsock winsock; #endif GOOGLE_PROTOBUF_VERIFY_VERSION; ::Flags flags; Try<flags::Warnings> load = flags.load("MESOS_", argc, argv); if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } if (flags.version) { cout << "mesos" << " " << MESOS_VERSION << endl; return EXIT_SUCCESS; } // TODO(marco): this pattern too should be abstracted away // in FlagsBase; I have seen it at least 15 times. if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.master.isNone() && flags.master_detector.isNone()) { cerr << flags.usage("Missing required option `--master` or " "`--master_detector`.") << endl; return EXIT_FAILURE; } if (flags.master.isSome() && flags.master_detector.isSome()) { cerr << flags.usage("Only one of --master or --master_detector options " "should be specified."); return EXIT_FAILURE; } // Initialize libprocess. if (flags.ip_discovery_command.isSome() && flags.ip.isSome()) { EXIT(EXIT_FAILURE) << flags.usage( "Only one of `--ip` or `--ip_discovery_command` should be specified"); } if (flags.ip_discovery_command.isSome()) { Try<string> ipAddress = os::shell(flags.ip_discovery_command.get()); if (ipAddress.isError()) { EXIT(EXIT_FAILURE) << ipAddress.error(); } os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get())); } else if (flags.ip.isSome()) { os::setenv("LIBPROCESS_IP", flags.ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(flags.port)); if (flags.advertise_ip.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_IP", flags.advertise_ip.get()); } if (flags.advertise_port.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_PORT", flags.advertise_port.get()); } // Log build information. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } const string id = process::ID::generate("slave"); // Process ID. // If `process::initialize()` returns `false`, then it was called before this // invocation, meaning the authentication realm for libprocess-level HTTP // endpoints was set incorrectly. This should be the first invocation. if (!process::initialize( id, READWRITE_HTTP_AUTHENTICATION_REALM, READONLY_HTTP_AUTHENTICATION_REALM)) { EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's " << "`main()` was not the function's first invocation"; } logging::initialize(argv[0], flags, true); // Catch signals. // Log any flag warnings (after logging is initialized). foreach (const flags::Warning& warning, load->warnings) { LOG(WARNING) << warning.message; } spawn(new VersionProcess(), true); if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
int main(int argc, char** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; slave::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on"); uint16_t port; flags.add(&port, "port", "Port to listen on", SlaveInfo().port()); Option<string> master; flags.add(&master, "master", "May be one of:\n" " zk://host1:port1,host2:port2,.../path\n" " zk://username:password@host1:port1,host2:port2,.../path\n" " file:///path/to/file (where file contains one of the above)"); Try<Nothing> load = flags.load("MESOS_", argc, argv); // TODO(marco): this pattern too should be abstracted away // in FlagsBase; I have seen it at least 15 times. if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } if (flags.version) { version(); return EXIT_SUCCESS; } if (master.isNone()) { cerr << flags.usage("Missing required option --master") << endl; return EXIT_FAILURE; } // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); } } // Initialize hooks. if (flags.hooks.isSome()) { Try<Nothing> result = HookManager::initialize(flags.hooks.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error(); } } // Initialize libprocess. if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); process::initialize("slave(1)"); logging::initialize(argv[0], flags, true); // Catch signals. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } Fetcher fetcher; Try<Containerizer*> containerizer = Containerizer::create(flags, false, &fetcher); if (containerizer.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a containerizer: " << containerizer.error(); } Try<MasterDetector*> detector = MasterDetector::create(master.get()); if (detector.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master detector: " << detector.error(); } if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
QString CompilerDriver_pix::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); if (cluster) { // PIX failover is dfferent from VRRP and other failover protocols // in that it does not create new virtual address. Instead, each // unit is configured with two ip addresses, one for the active // unit and another for standby one. When active unit fails, the // other one assumes its address. // // This matters because when we use cluster object or one of its // interfaces in rules, compiler should expand it to the set of // addresses that includes addresses of the corresponding // interface of both member firewalls. Method // CompilerDriver::copyFailoverInterface adds a copy of firewall // interface to the cluster object. This works for all firewalls, // but for PIX we need to add copies of interfaces from both // members. // FWObjectTypedChildIterator cl_iface = cluster->findByType(Interface::TYPENAME); for (; cl_iface != cl_iface.end(); ++cl_iface) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( (*cl_iface)->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { //FWObject *this_member_interface = NULL; //UNUSED list<FWObject*> other_member_interfaces; for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { FWObject *intf = FWObjectReference::getObject(*it); assert(intf); //if (intf->isChildOf(fw)) this_member_interface = intf; //UNUSED //else other_member_interfaces.push_back(intf); if (!intf->isChildOf(fw)) other_member_interfaces.push_back(intf); } if (!other_member_interfaces.empty()) { for (list<FWObject*>::iterator it=other_member_interfaces.begin(); it!=other_member_interfaces.end(); ++it) { cluster->addCopyOf(*it, true); } } } } } #if 0 FWObjectTypedChildIterator iface = fw->findByType(Interface::TYPENAME); for (; iface != iface.end(); ++iface) { (*iface)->dump(true, true); } #endif determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); FWOptions* options = fw->getOptionsObject(); QString script_buffer; std::auto_ptr<NATCompiler_pix> n; std::auto_ptr<PolicyCompiler_pix> c; std::auto_ptr<RoutingCompiler_pix> r; try { clearReadOnly(fw); commonChecks2(cluster, fw); pixClusterConfigurationChecks(cluster, fw); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); bool pix_acl_basic = options->getBool("pix_acl_basic"); bool pix_acl_no_clear = options->getBool("pix_acl_no_clear"); bool pix_acl_substitution = options->getBool("pix_acl_substitution"); bool pix_add_clear_statements = options->getBool("pix_add_clear_statements"); if (!pix_acl_basic && !pix_acl_no_clear && !pix_acl_substitution) { if ( pix_add_clear_statements ) options->setBool("pix_acl_basic",true); else options->setBool("pix_acl_no_clear",true); } list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); pixSecurityLevelChecks(fw, all_interfaces); pixNetworkZoneChecks(fw, all_interfaces); /* Now that all checks are done, we can drop copies of cluster * interfaces that were added to the firewall by * CompilerDriver::populateClusterElements() */ list<FWObject*> copies_of_cluster_interfaces; for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) copies_of_cluster_interfaces.push_back(iface); } while (copies_of_cluster_interfaces.size()) { fw->remove(copies_of_cluster_interfaces.front()); copies_of_cluster_interfaces.pop_front(); } NamedObjectsManagerPIX named_objects_manager(persistent_objects, fw); all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); /* * missing labels on interfaces * */ if (iface->getLabel()=="") { string lbl; if (iface->isDedicatedFailover()) { // dedicated failover interface misses label. This // interface can be used in failover cluster group // or state sync group. Assign label depending on // the function. FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(*it); if (state_sync_group && state_sync_group->hasMember(iface)) lbl = "state"; if (!iface->getOptionsObject()->getStr("failover_group_id").empty()) lbl = "failover"; } if (lbl.empty()) { if (iface->getSecurityLevel()==0) lbl="outside"; else { if (iface->getSecurityLevel()==100) lbl="inside"; else { QString l("dmz%1"); lbl = l.arg(iface->getSecurityLevel()).toStdString(); } } } iface->setLabel(lbl); } } /* * now sort interfaces by their network zone "width" (that * is, more narrow network zone should go first, interface * with network zone "any" should be the last) * std::sort(fw->begin(), fw->end(), sort_by_net_zone() ); */ try { AutomaticRules_cisco auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); } catch (FWException &ex) { abort(ex.toString()); } std::auto_ptr<Preprocessor> prep( new Preprocessor(objdb , fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); std::auto_ptr<OSConfigurator> oscnf( new OSConfigurator_pix_os(objdb , fw, false)); if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->prolog(); oscnf->processFirewallOptions(); bool have_named_objects = false; bool have_object_groups = false; /* create compilers and run the whole thing */ string version = fw->getStr("version"); if (XMLTools::version_compare(version, "8.3")>=0) n = std::auto_ptr<NATCompiler_pix>( new NATCompiler_asa8(objdb, fw, false, oscnf.get())); else n = std::auto_ptr<NATCompiler_pix>( new NATCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *nat = RuleSet::cast(fw->getFirstByType(NAT::TYPENAME)); if (nat) { nat->assignUniqueRuleIds(); n->setNamedObjectsManager(&named_objects_manager); n->setSourceRuleSet(nat); n->setRuleSetName(nat->getName()); n->setPersistentObjects(persistent_objects); if (inTestMode()) n->setTestMode(); if (inEmbeddedMode()) n->setEmbeddedMode(); n->setSingleRuleCompileMode(single_rule_id); n->setDebugLevel( dl ); if (rule_debug_on) n->setDebugRule( drn ); n->setVerbose( verbose ); if ( n->prolog() > 0 ) { n->compile(); n->epilog(); preamble_commands += n->printPreambleCommands(); clear_commands += n->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in NAT"); } c = std::auto_ptr<PolicyCompiler_pix>( new PolicyCompiler_pix(objdb, fw, false, oscnf.get() , n.get())); RuleSet *policy = RuleSet::cast(fw->getFirstByType(Policy::TYPENAME)); if (policy) { policy->assignUniqueRuleIds(); c->setNamedObjectsManager(&named_objects_manager); c->setSourceRuleSet(policy); c->setRuleSetName(policy->getName()); c->setPersistentObjects(persistent_objects); if (inTestMode()) c->setTestMode(); if (inEmbeddedMode()) c->setEmbeddedMode(); c->setSingleRuleCompileMode(single_rule_id); c->setDebugLevel( dl ); if (rule_debug_on) c->setDebugRule( drp ); c->setVerbose( verbose ); if ( c->prolog() > 0 ) { c->compile(); c->epilog(); preamble_commands += c->printPreambleCommands(); clear_commands += c->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in Policy"); } r = std::auto_ptr<RoutingCompiler_pix>( new RoutingCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing->assignUniqueRuleIds(); r->setNamedObjectsManager(&named_objects_manager); r->setSourceRuleSet(routing); r->setRuleSetName(routing->getName()); r->setPersistentObjects(persistent_objects); if (inTestMode()) r->setTestMode(); if (inEmbeddedMode()) r->setEmbeddedMode(); r->setSingleRuleCompileMode(single_rule_id); r->setDebugLevel( dl ); if (rule_debug_on) r->setDebugRule( drp ); r->setVerbose( verbose ); if ( r->prolog() > 0 ) { r->compile(); r->epilog(); } else info(" Nothing to compile in Routing"); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } policy_script = c->getCompiledScript(); nat_script = n->getCompiledScript(); routing_script = r->getCompiledScript(); named_objects_and_groups = named_objects_manager.getNamedObjectsDefinitions(); if (c->haveErrorsAndWarnings()) all_errors.push_back(c->getErrors("C ").c_str()); if (n->haveErrorsAndWarnings()) all_errors.push_back(n->getErrors("N ").c_str()); if (r->haveErrorsAndWarnings()) all_errors.push_back(r->getErrors("R ").c_str()); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (named_objects_and_groups + policy_script + nat_script + routing_script).c_str())); } system_configuration_script = oscnf->getCompiledScript(); system_configuration_script += "\n"; clear_commands += named_objects_manager.getClearCommands() + "\n"; // system_configuration_script += preamble_commands; // system_configuration_script += clear_commands; script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + ofname.toStdString()); QFile fw_file(ofname); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } if (!all_errors.isEmpty()) status = BaseCompiler::FWCOMPILER_WARNING; } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; }
QString CompilerDriver_junosacl::run(const string &cluster_id, const string &firewall_id, const string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); /* Now that all checks are done, we can drop copies of cluster * interfaces that were added to the firewall by * CompilerDriver::populateClusterElements() */ list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); list<FWObject*> copies_of_cluster_interfaces; for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) copies_of_cluster_interfaces.push_back(iface); } while (copies_of_cluster_interfaces.size()) { fw->remove(copies_of_cluster_interfaces.front()); copies_of_cluster_interfaces.pop_front(); } FWOptions* options = fw->getOptionsObject(); string fwvers = fw->getStr("version"); if (fwvers == "") fw->setStr("version", "11.2"); if (fwvers == "11.x") fw->setStr("version", "11.2"); string platform = fw->getStr("platform"); std::auto_ptr<OSConfigurator_junos> oscnf(new OSConfigurator_junos(objdb, fw, false)); oscnf->prolog(); oscnf->processFirewallOptions(); list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME); // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() // NB: these ids are not used by this compiler assignUniqueRuleIds(all_policies); vector<int> ipv4_6_runs; // // // // //NamedObjectsManager named_objects_manager(persistent_objects, fw); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } string object_groups_definitions; for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); // Count rules for each address family int policy_count = 0; for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (policy_count) { std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb, fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); } for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) continue; PolicyCompiler_junosacl c(objdb, fw, ipv6_policy, oscnf.get()); // // // // //c.setNamedObjectsManager(&named_objects_manager); c.setSourceRuleSet( policy ); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); c.setSingleRuleCompileMode(single_rule_id); if (inTestMode()) c.setTestMode(); if (inEmbeddedMode()) c.setEmbeddedMode(); c.setDebugLevel( dl ); if (rule_debug_on) c.setDebugRule( drp ); c.setVerbose( verbose ); if ( c.prolog() > 0) { c.compile(); c.epilog(); if (!single_rule_compile_on) { if (ipv6_policy) { policy_script += "\n\n"; policy_script += "# ================ IPv6\n"; policy_script += "\n\n"; } else { policy_script += "\n\n"; policy_script += "# ================ IPv4\n"; policy_script += "\n\n"; } } if (c.haveErrorsAndWarnings()) { all_errors.push_back(c.getErrors("").c_str()); } policy_script += c.getCompiledScript(); } else { info(" Nothing to compile in Policy"); } } } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } // // // // //object_groups_definitions += // // // // // named_objects_manager.getNamedObjectsDefinitions(); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (object_groups_definitions + policy_script).c_str())); } system_configuration_script += object_groups_definitions; QString script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); info("Output file name: " + ofname.toStdString()); QFile fw_file(ofname); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_buffer; fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } if (!all_errors.isEmpty()) status = BaseCompiler::FWCOMPILER_WARNING; } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8((ex.toString().c_str())); } return ""; }
void instDialog::fillCompileSelectList() { if (fwbdebug) qDebug("instDialog::fillCompileSelectList"); Firewall *fw; Cluster *cl; QDateTime dt; creatingTable = true; m_dialog->selectTable->clear(); list<Firewall*> working_list_of_firewalls = firewalls; for (list<Cluster *>::iterator i=clusters.begin(); i!=clusters.end(); ++i) { cl = *i; QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl); m_dialog->selectTable->addTopLevelItem(cluster_item); list<Firewall*> members; cl->getMembersList(members); for (list<Firewall*>::iterator member=members.begin(); member!=members.end(); ++member) { createTreeItem(cluster_item, *member); working_list_of_firewalls.remove(*member); } cluster_item->setExpanded(true); } for (list<Firewall *>::iterator i=working_list_of_firewalls.begin(); i!=working_list_of_firewalls.end(); ++i) { fw = *i; QTreeWidgetItem* fw_item = createTreeItem(NULL, fw); m_dialog->selectTable->addTopLevelItem(fw_item); } QTreeWidgetItemIterator it(m_dialog->selectTable); while (*it) { setFlags(*it); ++it; } /* ticket #1305 * check if any of the firewall objects are members of clusters but * the clusters are not requested for compile */ QString warn1( tr("<b>You are trying to compile policy for a firewall object that is " "a member of a cluster, however you requested compilation of only " "this member firewall and not the cluster it belongs to. Assuming " "firewall is standalone and not cluster member. Rules and parts of " "the script specific for the cluster configuration will not be " "generated.</b>")); QStringList warn2; list<FWObject*> all_libs = project->db()->getByType(Library::TYPENAME); foreach(FWObject *lib, all_libs) { if (lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) continue; list<FWObject*> all_clusters = lib->getByTypeDeep(Cluster::TYPENAME); foreach(FWObject *_cl, all_clusters) { if (std::find(clusters.begin(), clusters.end(), _cl) == clusters.end()) { Cluster *cluster = Cluster::cast(_cl); assert(cluster); foreach(FWObject *fw, firewalls) { if (cluster->hasMember(Firewall::cast(fw))) { warn2 << QString(tr("Firewall '%1' is member of cluster '%2'") .arg(QString::fromUtf8(fw->getName().c_str())) .arg(QString::fromUtf8(cluster->getPath().c_str()))); } } } } }
void FirewallDialog::applyChanges() { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges()"; bool autorename_chidren = false; QString dialog_txt = tr( "The name of the object '%1' has changed. The program can also " "rename IP address objects that belong to this object, " "using standard naming scheme 'host_name:interface_name:ip'. " "This makes it easier to distinguish what host or a firewall " "given IP address object belongs to when it is used in " "the policy or NAT rule. The program also renames MAC address " "objects using scheme 'host_name:interface_name:mac'. " "Do you want to rename child IP and MAC address objects now? " "(If you click 'No', names of all address objects that belong to " "%2 will stay the same.)") .arg(QString::fromUtf8(obj->getName().c_str())) .arg(QString::fromUtf8(obj->getName().c_str())); if (obj->getName() != m_dialog->obj_name->text().toUtf8().constData()) { /* * when we open this warning dialog, FirewallDialog class * loses focus and obj_name lineEdit widget sends signal * "editingfinished" again. To the user this looks like the * warning dialog popped up twice (in fact two copies of the * same warning dialog appear at the same time, one exactly on * top of another). To avoid this, block signals for the * duration while we show the dialog. Note that documentation * does not mention that QObject::blockSignals() affects not * only the widget but all its children, but it seems to work * that way. Tested with Qt 4.6.1. See #1171 */ blockSignals(true); autorename_chidren = (QMessageBox::warning( this,"Firewall Builder", dialog_txt, tr("&Yes"), tr("&No"), QString::null, 0, 1 )==0 ); blockSignals(false); } if (fwbdebug) qDebug() << "Sending FWCmdChange autorename_chidren=" << autorename_chidren; std::unique_ptr<FWCmdChange> cmd( new FWCmdChange(m_project, obj, "", autorename_chidren)); // new_state is a copy of the fw object FWObject* new_state = cmd->getNewState(); Firewall *s = dynamic_cast<Firewall*>(new_state); #ifndef NDEBUG Management *mgmt = s->getManagementObject(); assert(mgmt!=nullptr); #endif string old_name = obj->getName(); string new_name = string(m_dialog->obj_name->text().toUtf8().constData()); string old_platform = obj->getStr("platform"); string old_host_os = obj->getStr("host_OS"); string old_version = obj->getStr("version"); new_state->setName(new_name); m_dialog->commentKeywords->applyChanges(new_state); s->setInactive(m_dialog->inactive->isChecked()); saveVersion(new_state); string new_version = new_state->getStr("version"); string new_platform = readPlatform(m_dialog->platform).toLatin1().constData(); if (new_platform.empty()) new_platform = "unknown"; new_state->setStr("platform", new_platform ); if (old_platform!=new_platform) { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges() platform has changed" << old_platform.c_str() << "->" << new_platform.c_str() << "clearing option 'compiler'"; platformChanged(); FWOptions *opt =s->getOptionsObject(); opt->setStr("compiler", ""); // Set default options for the new platform Resources::setDefaultTargetOptions(new_platform, s); } string new_host_os = readHostOS(m_dialog->hostOS).toLatin1().constData(); if (new_host_os.empty()) new_host_os = "unknown_os"; new_state->setStr("host_OS", new_host_os); if (old_host_os!=new_host_os) { if (fwbdebug) qDebug() << "FirewallDialog::applyChanges() host_OS has changed" << old_host_os.c_str() << "->" << new_host_os.c_str(); hostOSChanged(); // Set default options for the new host os Resources::setDefaultTargetOptions(new_host_os, s); } if (new_platform.empty()) { QMessageBox::critical( this, "Firewall Builder", tr("Platform setting can not be empty"), tr("&Continue"), nullptr, nullptr, 0 ); return; } if (new_host_os.empty()) { QMessageBox::critical( this, "Firewall Builder", tr("Host OS setting can not be empty"), tr("&Continue"), nullptr, nullptr, 0 ); return; } if (old_platform!=new_platform || old_host_os!=new_host_os || old_name!=new_name || old_version!=new_version) { if (fwbdebug) qDebug("FirewallDialog::applyChanges() scheduling call " "to reopenFirewall()"); m_project->registerRuleSetRedrawRequest(); } if (!cmd->getOldState()->cmp(new_state, true)) { if (obj->isReadOnly()) return; m_project->undoStack->push(cmd.release()); } updateTimeStamps(); }
int main(int argc, char** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; slave::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on. This cannot be used in conjunction\n" "with `--ip_discovery_command`."); uint16_t port; flags.add(&port, "port", "Port to listen on.", SlaveInfo().port()); Option<string> advertise_ip; flags.add(&advertise_ip, "advertise_ip", "IP address advertised to reach this Mesos agent.\n" "The agent does not bind to this IP address.\n" "However, this IP address may be used to access this agent."); Option<string> advertise_port; flags.add(&advertise_port, "advertise_port", "Port advertised to reach this Mesos agent (along with\n" "`advertise_ip`). The agent does not bind to this port.\n" "However, this port (along with `advertise_ip`) may be used to\n" "access this agent."); Option<string> master; flags.add(&master, "master", "May be one of:\n" " `host:port`\n" " `zk://host1:port1,host2:port2,.../path`\n" " `zk://username:password@host1:port1,host2:port2,.../path`\n" " `file:///path/to/file` (where file contains one of the above)"); // Optional IP discover script that will set the slave's IP. // If set, its output is expected to be a valid parseable IP string. Option<string> ip_discovery_command; flags.add(&ip_discovery_command, "ip_discovery_command", "Optional IP discovery binary: if set, it is expected to emit\n" "the IP address which the agent will try to bind to.\n" "Cannot be used in conjunction with `--ip`."); Try<Nothing> load = flags.load("MESOS_", argc, argv); // TODO(marco): this pattern too should be abstracted away // in FlagsBase; I have seen it at least 15 times. if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } if (flags.version) { version(); return EXIT_SUCCESS; } if (master.isNone() && flags.master_detector.isNone()) { cerr << flags.usage("Missing required option `--master` or " "`--master_detector`.") << endl; return EXIT_FAILURE; } if (master.isSome() && flags.master_detector.isSome()) { cerr << flags.usage("Only one of --master or --master_detector options " "should be specified."); return EXIT_FAILURE; } // Initialize libprocess. if (ip_discovery_command.isSome() && ip.isSome()) { EXIT(EXIT_FAILURE) << flags.usage( "Only one of `--ip` or `--ip_discovery_command` should be specified"); } if (ip_discovery_command.isSome()) { Try<string> ipAddress = os::shell(ip_discovery_command.get()); if (ipAddress.isError()) { EXIT(EXIT_FAILURE) << ipAddress.error(); } os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get())); } else if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); if (advertise_ip.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get()); } if (advertise_port.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get()); } const string id = process::ID::generate("slave"); // Process ID. // If `process::initialize()` returns `false`, then it was called before this // invocation, meaning the authentication realm for libprocess-level HTTP // endpoints was set incorrectly. This should be the first invocation. if (!process::initialize(id, DEFAULT_HTTP_AUTHENTICATION_REALM)) { EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's " << "`main()` was not the function's first invocation"; } logging::initialize(argv[0], flags, true); // Catch signals. // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); } } // Initialize hooks. if (flags.hooks.isSome()) { Try<Nothing> result = HookManager::initialize(flags.hooks.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error(); } } spawn(new VersionProcess(), true); LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } Fetcher fetcher; #ifdef __linux__ // Initialize systemd if it exists. if (systemd::exists() && flags.systemd_enable_support) { LOG(INFO) << "Inializing systemd state"; systemd::Flags systemdFlags; systemdFlags.enabled = flags.systemd_enable_support; systemdFlags.runtime_directory = flags.systemd_runtime_directory; systemdFlags.cgroups_hierarchy = flags.cgroups_hierarchy; Try<Nothing> initialize = systemd::initialize(systemdFlags); if (initialize.isError()) { EXIT(EXIT_FAILURE) << "Failed to initialize systemd: " + initialize.error(); } } #endif // __linux__ Try<Containerizer*> containerizer = Containerizer::create(flags, false, &fetcher); if (containerizer.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a containerizer: " << containerizer.error(); } Try<MasterDetector*> detector_ = MasterDetector::create( master, flags.master_detector); if (detector_.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master detector: " << detector_.error(); } MasterDetector* detector = detector_.get(); Option<Authorizer*> authorizer_ = None(); string authorizerName = flags.authorizer; Result<Authorizer*> authorizer((None())); if (authorizerName != slave::DEFAULT_AUTHORIZER) { LOG(INFO) << "Creating '" << authorizerName << "' authorizer"; // NOTE: The contents of --acls will be ignored. authorizer = Authorizer::create(authorizerName); } else { // `authorizerName` is `DEFAULT_AUTHORIZER` at this point. if (flags.acls.isSome()) { LOG(INFO) << "Creating default '" << authorizerName << "' authorizer"; authorizer = Authorizer::create(flags.acls.get()); } } if (authorizer.isError()) { EXIT(EXIT_FAILURE) << "Could not create '" << authorizerName << "' authorizer: " << authorizer.error(); } else if (authorizer.isSome()) { authorizer_ = authorizer.get(); } if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
bool ProjectPanel::event(QEvent *event) { if (event->type() >= QEvent::User) { fwbUpdateEvent *ev = dynamic_cast<fwbUpdateEvent*>(event); int event_code = event->type() - QEvent::User; QString data_file = ev->getFileName(); int obj_id = ev->getObjectId(); FWObject *obj = db()->findInIndex(obj_id); if (fwbdebug) qDebug() << this << "rcs:" << rcs << "rcs->getFileName():" << QString((rcs!=NULL) ? rcs->getFileName() : "") << "file:" << data_file << "event:" << ev->getEventName() << "object:" << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "") << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")" << "id=" << ((obj!=NULL) ? obj->getId() : -1); if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL) { m_panel->om->updateCreateObjectMenu(getCurrentLib()); ev->accept(); return true; } if ((rcs && rcs->getFileName() == data_file) || (!rcs && data_file.isEmpty())) { switch (event_code) { case RELOAD_OBJECT_TREE_EVENT: registerTreeReloadRequest(); ev->accept(); return true; case RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT: m_panel->om->reload(); ev->accept(); return true; case RELOAD_RULESET_EVENT: registerRuleSetRedrawRequest(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); if (rsv) rsv->makeCurrentRuleVisible(); ev->accept(); return true; } case RELOAD_RULESET_IMMEDIATELY_EVENT: redrawRuleSets(); //reopenFirewall(); // update rule set title as well //updateFirewallName(); ev->accept(); return true; } if (obj == NULL) return false; switch (event_code) { case DATA_MODIFIED_EVENT: { // This event does not trigger any updates in the UI, // this purely data structure update event. FWObject *p = obj; while (p && Firewall::cast(p)==NULL) p = p->getParent(); Firewall *f = Firewall::cast(p); // when user locks firewall object, this code tries to // update last_modified timestamp in it because it // depends on itself. Dont. if (f && !f->isReadOnly()) { f->updateLastModifiedTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, f->getId())); } registerModifiedObject(obj); QCoreApplication::postEvent(mw, new updateGUIStateEvent()); ev->accept(); return true; } case UPDATE_OBJECT_EVERYWHERE_EVENT: { Rule *rule = NULL; RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (RuleElement::cast(obj)) rule = Rule::cast(obj->getParent()); if (Rule::cast(obj)) rule = Rule::cast(obj); if (rule && current_ruleset && md && rule->isChildOf(current_ruleset)) { md->rowChanged(md->index(rule, 0)); ev->accept(); return true; } if (rule) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); ev->accept(); return true; } if (rsv) rsv->updateObject(obj); if (Library::cast(obj)) { m_panel->om->updateLibName(obj); m_panel->om->updateLibColor(obj); } QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); // QCoreApplication::postEvent( // this, new reloadRulesetEvent(data_file)); ev->accept(); return true; } case OBJECT_NAME_CHANGED_EVENT: { objectNameChangedEvent *name_change_event = dynamic_cast<objectNameChangedEvent*>(event); m_panel->om->updateObjectInTree(obj); if (name_change_event->rename_children) { // This performs automatic renaming of child objects if necessary m_panel->om->autoRenameChildren(obj, name_change_event->old_name); } ev->accept(); return true; } case UPDATE_LAST_COMPILED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastCompiledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; case UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT: if (rcs && !rcs->isRO() && Firewall::cast(obj) && !obj->isReadOnly()) { Firewall::cast(obj)->updateLastInstalledTimestamp(); QCoreApplication::postEvent( mw, new updateObjectInTreeEvent(data_file, obj_id)); ev->accept(); return true; } break; } // Events below this should only be processed if // ProjectPanel has been attached to an MDI window. There // is no MDI window right after project panel is created // but some operations may already be performed. See // FWWindow::fileOpen where ProjectPanel is cfeated and // file is opened before MDI window is attached. So the UI // update events below will only be processed if MDI // window exists. if (mdiWindow == NULL) return false; switch (event->type() - QEvent::User) { case INSERT_OBJECT_IN_TREE_EVENT: { FWObject *parent = db()->findInIndex( dynamic_cast<insertObjectInTreeEvent*>(event)->parent_id); m_panel->om->insertSubtree(parent, obj); ev->accept(); return true; } case REMOVE_OBJECT_FROM_TREE_EVENT: { m_panel->om->removeObjectFromTreeView(obj); ev->accept(); return true; } case ADD_TREE_PAGE_EVENT: m_panel->om->addLib(obj); ev->accept(); return true; case REMOVE_TREE_PAGE_EVENT: m_panel->om->removeLib(obj); ev->accept(); return true; case UPDATE_OBJECT_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, false); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT: registerObjectToUpdateInTree(obj, true); ev->accept(); return true; case UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT: m_panel->om->updateObjectInTree(obj, true); ev->accept(); return true; case OPEN_RULESET_EVENT: openRuleSet(obj); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case OPEN_RULESET_IMMEDIATELY_EVENT: openRuleSet(obj, true); // update rule set title as well //updateFirewallName(); ev->accept(); return true; case SELECT_RULE_ELEMENT_EVENT: { RuleSetView* rsv = getCurrentRuleSetView(); rsv->selectRE(Rule::cast(obj), dynamic_cast<selectRuleElementEvent*>(event)->column_type); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } case SHOW_OBJECT_IN_RULESET_EVENT: { // if obj is child of RuleElement (i.e. a reference object) FWReference *ref = FWReference::cast(obj); if (ref) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && obj->isChildOf(current_ruleset)) { clearManipulatorFocus(); rsv->selectRE(ref); rsv->setFocus(Qt::OtherFocusReason); } else { FWObject *rs = obj; while (rs && RuleSet::cast(rs)==NULL) rs = rs->getParent(); if (rs) { // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rs); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj_id)); } } ev->accept(); return true; } // if obj is RuleElement - select its first element RuleElement *re = RuleElement::cast(obj); if (re && re->size() > 0) { QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->front()->getId())); ev->accept(); return true; } // if obj is Rule - select its comment (the only common rule element) Rule *rule = Rule::cast(obj); if (rule) { RuleSet* current_ruleset = NULL; RuleSetView* rsv = getCurrentRuleSetView(); RuleSetModel* md = NULL; if (rsv) { md = (RuleSetModel*)rsv->model(); current_ruleset = md->getRuleSet(); } if (current_ruleset && rule->isChildOf(current_ruleset)) { rsv->selectRE(rule, ColDesc::Comment); rsv->setFocus(Qt::OtherFocusReason); ev->accept(); return true; } else { // this rule does not belong to the current ruleset // reopen rule set right now, before we post event // to show the object in it. openRuleSet(rule->getParent(), true); QCoreApplication::postEvent( this, new showObjectInRulesetEvent(data_file, obj->getId())); } ev->accept(); return true; } ev->accept(); return true; } case SHOW_OBJECT_IN_TREE_EVENT: //m_panel->om->setFocus(); m_panel->om->openObjectInTree(obj); ev->accept(); return true; case EXPAND_OBJECT_IN_TREE: m_panel->om->expandObjectInTree(obj); ev->accept(); return true; case OPEN_LIBRARY_FOR_OBJECT_EVENT: m_panel->om->openLibForObject(obj); ev->accept(); return true; case CLOSE_OBJECT_EVENT: if (RuleSet::cast(obj)) { if (visibleRuleSet == obj) { clearFirewallTabs(); closeRuleSet(obj); } } else { m_panel->om->closeObject(); mdiWindow->update(); } ev->accept(); return true; case ADD_USER_FOLDER_EVENT: m_panel->om->addUserFolderToTree(obj, dynamic_cast<addUserFolderEvent *>(event)->m_userFolder); ev->accept(); return true; case REMOVE_USER_FOLDER_EVENT: m_panel->om->removeUserFolderFromTree(obj, dynamic_cast<removeUserFolderEvent *>(event)->m_userFolder); ev->accept(); return true; case MOVE_TOFROM_USER_FOLDER_EVENT: moveToFromUserFolderEvent *moveEvent = dynamic_cast<moveToFromUserFolderEvent *>(event); m_panel->om->moveToFromUserFolderInTree(obj, db()->findInIndex(moveEvent->m_objIdToMove), moveEvent->m_oldFolder, moveEvent->m_newFolder); ev->accept(); return true; } } return false; } //if (fwbdebug) qDebug() << this << "event:" << event; return QWidget::event(event); }
/** * finds interface of the firewall associated with the netzone * that object 'obj' belongs to. Returns interface ID * */ int Helper::findInterfaceByNetzone(const InetAddr *addr, const InetAddr *nm) throw(FWException) { #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " matching to"; cerr << " addr=" << addr; if (addr) cerr << " " << addr->toString(); cerr << " nm=" << nm; if (nm) cerr << " " << nm->toString(); cerr << endl; #endif Firewall *fw = compiler->fw; map<int,FWObject*> zones; list<FWObject*> l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->isDedicatedFailover()) continue; if (iface->isUnprotected()) continue; // NOTE: "network_zone" is globally unique string ID int netzone_id = FWObjectDatabase::getIntId(iface->getStr("network_zone")); if (netzone_id != -1) { FWObject *netzone = fw->getRoot()->findInIndex(netzone_id); list<FWObject*> nz; expand_group_recursive(netzone, nz); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " netzone_id=" << netzone_id << " " << iface->getStr("network_zone") << " " << netzone->getName() << endl; #endif for (list<FWObject*>::iterator j=nz.begin(); j!=nz.end(); ++j) { Address *netzone_addr = Address::cast(*j); if (netzone_addr == NULL) continue; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " " << netzone_addr->getName() << " " << netzone_addr->getAddressPtr()->toString() << endl; #endif // if addr==NULL, return id of the interfacce that has // net_zone=="any" if (addr==NULL) { if (netzone_addr->getId()==FWObjectDatabase::ANY_ADDRESS_ID) return iface->getId(); // id of the interface } else { // see SF bug 3213019 // skip ipv6 addresses in network zone group if (netzone_addr->getAddressPtr()->addressFamily() != addr->addressFamily()) continue; const InetAddr *nz_addr = netzone_addr->getAddressPtr(); const InetAddr *nz_netm = netzone_addr->getNetmaskPtr(); if (nm != NULL && nz_netm != NULL) { InetAddrMask nz_subnet(*nz_addr, *nz_netm); InetAddrMask other_subnet(*addr, *nm); vector<InetAddrMask> ovr = libfwbuilder::getOverlap(nz_subnet, other_subnet); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " addr=" << other_subnet.toString(); cerr << " nz=" << nz_subnet.toString(); cerr << " overlap:"; cerr << " ovr.size()=" << ovr.size(); if (ovr.size() > 0) cerr << " ovr.front()=" << ovr.front().toString(); cerr << endl; #endif if (ovr.size()==0) continue; // if nz_subnet is equal or wider than other_subnet, // getOverlap() returns subnet object equal to other_subnet // If other_subnet is wider, returned object is equal // to nz_subnet. If they intersect but one does not fit // completely in the other, returned object is not equal // to either. if (ovr.front() == other_subnet) { zones[iface->getId()] = netzone_addr; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " match" << endl; #endif } } else { if (netzone_addr->belongs(*addr)) { zones[iface->getId()] = netzone_addr; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " match" << endl; #endif } } } } } } /* * now compare dimensions of all netzones that contain address obj and * pick the one with smallest dimension */ int res_id = -1; unsigned long res_dim = LONG_MAX; for (map<int,FWObject*>::iterator i=zones.begin(); i!=zones.end(); ++i) { int iface_id = (*i).first; FWObject *netzone = (*i).second; unsigned long dim = calculateDimension(netzone); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " netzone=" << netzone->getName() << " dim=" << dim << " res_dim=" << res_dim << endl; #endif if (dim<=res_dim) { res_id = iface_id; res_dim = dim; } } #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " Result after scanning network zones: " << res_id << endl; #endif /* * Subnets defined by addresses of interfaces are automatically part * of the corresponding network zones */ if (res_id == -1) res_id = findInterfaceByAddress(addr, nm); if (res_id == -1) { QString err = QObject::tr("Can not find interface with network zone " "that includes address '%1%2'"); throw(FWException(err .arg((addr)?addr->toString().c_str():"NULL") .arg((nm)?QString("/%1").arg(nm->toString().c_str()):"") .toStdString())); } #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByNetzone"; cerr << " returning " << res_id << endl; #endif return res_id; }
int Helper::findInterfaceByAddress(const InetAddr *addr, const InetAddr *nm) { if (addr==NULL) return -1; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " addr=" << addr->toString(); cerr << " nm=" << nm->toString(); cerr << endl; #endif Firewall *fw = compiler->fw; list<FWObject*> l2 = fw->getByTypeDeep(Interface::TYPENAME); for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i) { Interface *iface = Interface::cast(*i); if (iface->isDedicatedFailover()) continue; if (iface->isUnprotected()) continue; #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " intf=" << iface->getName(); cerr << endl; #endif FWObjectTypedChildIterator j = iface->findByType((addr->isV4())?IPv4::TYPENAME:IPv6::TYPENAME); for (; j!=j.end(); ++j) { const Address *i_addr = Address::constcast(*j); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " i_addr=" << i_addr->getName(); cerr << endl; cerr << " " << i_addr->getAddressPtr()->toString(); cerr << " " << i_addr->getNetmaskPtr()->toString(); cerr << endl; #endif if (nm != NULL) { InetAddrMask interface_subnet(*(i_addr->getAddressPtr()), *(i_addr->getNetmaskPtr())); InetAddrMask other_subnet(*addr, *nm); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " addr=" << other_subnet.toString(); cerr << " intf=" << iface->getName() << " " << interface_subnet.toString(); cerr << endl; #endif vector<InetAddrMask> ovr = libfwbuilder::getOverlap(interface_subnet, other_subnet); #if DEBUG_NETZONE_OPS cerr << "Helper::findInterfaceByAddress"; cerr << " overlap:"; cerr << " ovr.size()=" << ovr.size(); if (ovr.size() > 0) cerr << " ovr.front()=" << ovr.front().toString(); cerr << endl; #endif if (ovr.size()==0) continue; // if interface_subnet is equal or wider than other_subnet, // getOverlap() returns subnet object equal to other_subnet // If other_subnet is wider, returned object is equal // to interface_subnet. If they intersect but one does not fit // completely in the other, returned object is not equal // to either. if (ovr.front() == other_subnet) { return iface->getId(); } } else { if ( i_addr->belongs(*addr) ) return iface->getId(); } } } return -1; }
int main(int argc, char** argv) { // The order of initialization is as follows: // * Windows socket stack. // * Validate flags. // * Log build information. // * Libprocess // * Logging // * Version process // * Firewall rules: should be initialized before initializing HTTP endpoints. // * Modules: Load module libraries and manifests before they // can be instantiated. // * Anonymous modules: Later components such as Allocators, and master // contender/detector might depend upon anonymous modules. // * Hooks. // * Systemd support (if it exists). // * Fetcher and Containerizer. // * Master detector. // * Authorizer. // * Garbage collector. // * Status update manager. // * Resource estimator. // * QoS controller. // * `Agent` process. // // TODO(avinash): Add more comments discussing the rationale behind for this // particular component ordering. #ifdef __WINDOWS__ // Initialize the Windows socket stack. process::Winsock winsock; #endif GOOGLE_PROTOBUF_VERIFY_VERSION; slave::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on. This cannot be used in conjunction\n" "with `--ip_discovery_command`."); uint16_t port; flags.add(&port, "port", "Port to listen on.", SlaveInfo().port()); Option<string> advertise_ip; flags.add(&advertise_ip, "advertise_ip", "IP address advertised to reach this Mesos agent.\n" "The agent does not bind to this IP address.\n" "However, this IP address may be used to access this agent."); Option<string> advertise_port; flags.add(&advertise_port, "advertise_port", "Port advertised to reach this Mesos agent (along with\n" "`advertise_ip`). The agent does not bind to this port.\n" "However, this port (along with `advertise_ip`) may be used to\n" "access this agent."); Option<string> master; flags.add(&master, "master", "May be one of:\n" " `host:port`\n" " `zk://host1:port1,host2:port2,.../path`\n" " `zk://username:password@host1:port1,host2:port2,.../path`\n" " `file:///path/to/file` (where file contains one of the above)"); // Optional IP discover script that will set the slave's IP. // If set, its output is expected to be a valid parseable IP string. Option<string> ip_discovery_command; flags.add(&ip_discovery_command, "ip_discovery_command", "Optional IP discovery binary: if set, it is expected to emit\n" "the IP address which the agent will try to bind to.\n" "Cannot be used in conjunction with `--ip`."); Try<flags::Warnings> load = flags.load("MESOS_", argc, argv); // TODO(marco): this pattern too should be abstracted away // in FlagsBase; I have seen it at least 15 times. if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } if (flags.version) { cout << "mesos" << " " << MESOS_VERSION << endl; return EXIT_SUCCESS; } if (master.isNone() && flags.master_detector.isNone()) { cerr << flags.usage("Missing required option `--master` or " "`--master_detector`.") << endl; return EXIT_FAILURE; } if (master.isSome() && flags.master_detector.isSome()) { cerr << flags.usage("Only one of --master or --master_detector options " "should be specified."); return EXIT_FAILURE; } // Initialize libprocess. if (ip_discovery_command.isSome() && ip.isSome()) { EXIT(EXIT_FAILURE) << flags.usage( "Only one of `--ip` or `--ip_discovery_command` should be specified"); } if (ip_discovery_command.isSome()) { Try<string> ipAddress = os::shell(ip_discovery_command.get()); if (ipAddress.isError()) { EXIT(EXIT_FAILURE) << ipAddress.error(); } os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get())); } else if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); if (advertise_ip.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get()); } if (advertise_port.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get()); } // Log build information. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } const string id = process::ID::generate("slave"); // Process ID. // If `process::initialize()` returns `false`, then it was called before this // invocation, meaning the authentication realm for libprocess-level HTTP // endpoints was set incorrectly. This should be the first invocation. if (!process::initialize(id, DEFAULT_HTTP_AUTHENTICATION_REALM)) { EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's " << "`main()` was not the function's first invocation"; } logging::initialize(argv[0], flags, true); // Catch signals. // Log any flag warnings (after logging is initialized). foreach (const flags::Warning& warning, load->warnings) { LOG(WARNING) << warning.message; } spawn(new VersionProcess(), true); if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
void FirewallDialog::loadFWObject(FWObject *o) { try { obj = o; Firewall *s = dynamic_cast<Firewall*>(obj); assert(s!=nullptr); init = true; QString platform = obj->getStr("platform").c_str(); /* fill in platform */ setPlatform(m_dialog->platform, platform); fillVersion(); /* fill in host OS */ setHostOS(m_dialog->hostOS, platform, obj->getStr("host_OS").c_str()); /* ---------------- */ updateTimeStamps(); #ifndef NDEBUG Management *mgmt=s->getManagementObject(); assert(mgmt!=nullptr); #endif // FWOptions *opt =s->getOptionsObject(); m_dialog->obj_name->setText( QString::fromUtf8(s->getName().c_str()) ); m_dialog->commentKeywords->loadFWObject(o); m_dialog->inactive->setChecked(s->getInactive()); m_dialog->obj_name->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->obj_name); m_dialog->platform->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->platform); m_dialog->version->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->version); m_dialog->hostOS->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->hostOS); m_dialog->fwAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->fwAdvanced); m_dialog->osAdvanced->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->osAdvanced); // snmpCommunity->setEnabled(!o->isReadOnly()); // setDisabledPalette(snmpCommunity); m_dialog->inactive->setEnabled(!o->isReadOnly()); setDisabledPalette(m_dialog->inactive); } catch (FWException &ex) { qDebug() << "Caught FWException:" << ex.toString().c_str(); } init=false; }
int main(int argc, char** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; master::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on"); uint16_t port; flags.add(&port, "port", "Port to listen on", MasterInfo().port()); Option<string> advertise_ip; flags.add(&advertise_ip, "advertise_ip", "IP address advertised to reach mesos master.\n" "Mesos master does not bind using this IP address.\n" "However, this IP address may be used to access Mesos master."); Option<string> advertise_port; flags.add(&advertise_port, "advertise_port", "Port advertised to reach mesos master (alongwith advertise_ip).\n" "Mesos master does not bind using this port.\n" "However, this port (alongwith advertise_ip) may be used to\n" "access Mesos master."); Option<string> zk; flags.add(&zk, "zk", "ZooKeeper URL (used for leader election amongst masters)\n" "May be one of:\n" " zk://host1:port1,host2:port2,.../path\n" " zk://username:password@host1:port1,host2:port2,.../path\n" " file:///path/to/file (where file contains one of the above)"); // Optional IP discover script that will set the Master IP. // If set, its output is expected to be a valid parseable IP string. Option<string> ip_discovery_command; flags.add(&ip_discovery_command, "ip_discovery_command", "Optional IP discovery binary: if set, it is expected to emit\n" "the IP address which Master will try to bind to.\n" "Cannot be used in conjunction with --ip."); Try<Nothing> load = flags.load("MESOS_", argc, argv); if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.version) { version(); return EXIT_SUCCESS; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); } } // Initialize hooks. if (flags.hooks.isSome()) { Try<Nothing> result = HookManager::initialize(flags.hooks.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error(); } } if (ip_discovery_command.isSome() && ip.isSome()) { EXIT(EXIT_FAILURE) << flags.usage( "Only one of --ip or --ip_discovery_command should be specified"); } if (ip_discovery_command.isSome()) { Try<string> ipAddress = os::shell(ip_discovery_command.get()); if (ipAddress.isError()) { EXIT(EXIT_FAILURE) << ipAddress.error(); } os::setenv("LIBPROCESS_IP", strings::trim(ipAddress.get())); } else if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); if (advertise_ip.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_IP", advertise_ip.get()); } if (advertise_port.isSome()) { os::setenv("LIBPROCESS_ADVERTISE_PORT", advertise_port.get()); } // Initialize libprocess. process::initialize("master"); logging::initialize(argv[0], flags, true); // Catch signals. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } // Create an instance of allocator. const std::string allocatorName = flags.allocator; Try<Allocator*> allocator = Allocator::create(allocatorName); if (allocator.isError()) { EXIT(EXIT_FAILURE) << "Failed to create '" << allocatorName << "' allocator: " << allocator.error(); } CHECK_NOTNULL(allocator.get()); LOG(INFO) << "Using '" << allocatorName << "' allocator"; state::Storage* storage = NULL; Log* log = NULL; if (flags.registry == "in_memory") { if (flags.registry_strict) { EXIT(EXIT_FAILURE) << "Cannot use '--registry_strict' when using in-memory storage" << " based registry"; } storage = new state::InMemoryStorage(); } else if (flags.registry == "replicated_log" || flags.registry == "log_storage") { // TODO(bmahler): "log_storage" is present for backwards // compatibility, can be removed before 0.19.0. if (flags.work_dir.isNone()) { EXIT(EXIT_FAILURE) << "--work_dir needed for replicated log based registry"; } Try<Nothing> mkdir = os::mkdir(flags.work_dir.get()); if (mkdir.isError()) { EXIT(EXIT_FAILURE) << "Failed to create work directory '" << flags.work_dir.get() << "': " << mkdir.error(); } if (zk.isSome()) { // Use replicated log with ZooKeeper. if (flags.quorum.isNone()) { EXIT(EXIT_FAILURE) << "Need to specify --quorum for replicated log based" << " registry when using ZooKeeper"; } Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get()); if (url.isError()) { EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error(); } log = new Log( flags.quorum.get(), path::join(flags.work_dir.get(), "replicated_log"), url.get().servers, flags.zk_session_timeout, path::join(url.get().path, "log_replicas"), url.get().authentication, flags.log_auto_initialize); } else { // Use replicated log without ZooKeeper. log = new Log( 1, path::join(flags.work_dir.get(), "replicated_log"), set<UPID>(), flags.log_auto_initialize); } storage = new state::LogStorage(log); } else { EXIT(EXIT_FAILURE) << "'" << flags.registry << "' is not a supported" << " option for registry persistence"; } CHECK_NOTNULL(storage); state::protobuf::State* state = new state::protobuf::State(storage); Registrar* registrar = new Registrar(flags, state); Repairer* repairer = new Repairer(); Files files; MasterContender* contender; MasterDetector* detector; // TODO(vinod): 'MasterContender::create()' should take // Option<string>. Try<MasterContender*> contender_ = MasterContender::create(zk.getOrElse("")); if (contender_.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master contender: " << contender_.error(); } contender = contender_.get(); // TODO(vinod): 'MasterDetector::create()' should take // Option<string>. Try<MasterDetector*> detector_ = MasterDetector::create(zk.getOrElse("")); if (detector_.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master detector: " << detector_.error(); } detector = detector_.get(); Option<Authorizer*> authorizer = None(); auto authorizerNames = strings::split(flags.authorizers, ","); if (authorizerNames.empty()) { EXIT(EXIT_FAILURE) << "No authorizer specified"; } if (authorizerNames.size() > 1) { EXIT(EXIT_FAILURE) << "Multiple authorizers not supported"; } std::string authorizerName = authorizerNames[0]; // NOTE: The flag --authorizers overrides the flag --acls, i.e. if // a non default authorizer is requested, it will be used and // the contents of --acls will be ignored. // TODO(arojas): Add support for multiple authorizers. if (authorizerName != master::DEFAULT_AUTHORIZER || flags.acls.isSome()) { Try<Authorizer*> create = Authorizer::create(authorizerName); if (create.isError()) { EXIT(EXIT_FAILURE) << "Could not create '" << authorizerName << "' authorizer: " << create.error(); } authorizer = create.get(); LOG(INFO) << "Using '" << authorizerName << "' authorizer"; if (authorizerName == master::DEFAULT_AUTHORIZER) { Try<Nothing> initialize = authorizer.get()->initialize(flags.acls.get()); if (initialize.isError()) { // Failing to initialize the authorizer leads to undefined // behavior, therefore we default to skip authorization // altogether. LOG(WARNING) << "Authorization disabled: Failed to initialize '" << authorizerName << "' authorizer: " << initialize.error(); delete authorizer.get(); authorizer = None(); } } else if (flags.acls.isSome()) { LOG(WARNING) << "Ignoring contents of --acls flag, because '" << authorizerName << "' authorizer will be used instead " << " of the default."; } } Option<shared_ptr<RateLimiter>> slaveRemovalLimiter = None(); if (flags.slave_removal_rate_limit.isSome()) { // Parse the flag value. // TODO(vinod): Move this parsing logic to flags once we have a // 'Rate' abstraction in stout. vector<string> tokens = strings::tokenize(flags.slave_removal_rate_limit.get(), "/"); if (tokens.size() != 2) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>"; } Try<int> permits = numify<int>(tokens[0]); if (permits.isError()) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>" << ": " << permits.error(); } Try<Duration> duration = Duration::parse(tokens[1]); if (duration.isError()) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>" << ": " << duration.error(); } slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get()); } if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
/* * Go through paces to compile firewall which may be a member of a * cluster. Note that both firewall and cluster are defined by their * unique string IDs. This is necessary because CompilerDriver * operates with a copy of the object database which is not exposed * outside, so the caller can not provide pointers to these obejcts. */ QString CompilerDriver_ipt::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { FWObjectDatabase::registerObjectType(combinedAddress::TYPENAME, &create_combinedAddress); // see #2212 Create temporary copy of the firewall and cluster // objects and pass them to the compilers. Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); string generated_script; try { clearReadOnly(fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); commonChecks2(cluster, fw); string fw_version = fw->getStr("version"); if (fw_version.empty()) fw_version = "(any version)"; string platform = fw->getStr("platform"); string host_os = fw->getStr("host_OS"); FWOptions* options = fw->getOptionsObject(); string s; // Note that fwobjectname may be different from the name of the // firewall fw This happens when we compile a member of a cluster current_firewall_name = fw->getName().c_str(); if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" && fw->getOptionsObject()->getBool("use_iptables_restore")) { abort("Prolog place \"after policy reset\" can not be used" " when policy is activated with iptables-restore"); } string firewall_dir = options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir="/etc"; bool debug=options->getBool("debug"); QString shell_dbg = (debug)?"set -x":"" ; std::auto_ptr<OSConfigurator_linux24> oscnf; string platform_family = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/family"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); bool supports_prolog_epilog = Resources::getTargetCapabilityBool( platform, "supports_prolog_epilog"); if (!supports_prolog_epilog) { prolog_done = true; epilog_done = true; } string os_variant = DISTRO; /* minimal sanity checking */ if (os_family == "ipcop") { os_variant = "ipcop"; // can't use iptables-restore with ipcop fw->getOptionsObject()->setBool("use_iptables_restore", false); // ipcop has its own iptables commands that accept packets // in states ESTABLISHED,RELATED fw->getOptionsObject()->setBool("accept_established", false); oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_ipcop(objdb , fw, false)); } if (os_family == "linux24" || os_family == "openwrt" || os_family == "dd-wrt-nvram" || os_family == "dd-wrt-jffs" || os_family == "sveasoft") oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_linux24(objdb , fw, false)); if (os_family == "secuwall") oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_secuwall(objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + fw->getStr("host_OS") + " (family " + os_family+")"); return ""; } if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->validateInterfaces(); oscnf->prolog(); list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME); list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME); int routing_rules_count = 0; bool have_ipv4 = false; bool have_ipv6 = false; // track chains in each table separately. Can we have the same // chain in filter and mangle tables ? Would it be the same // chain, i.e. do we need to create it only once or do we create // it twice, in each table separately ? // Using separate trackers we track and create chain in each // table separately. std::map<const std::string, bool> minus_n_commands_filter; std::map<const std::string, bool> minus_n_commands_mangle; std::map<const std::string, bool> minus_n_commands_nat; vector<int> ipv4_6_runs; findImportedRuleSets(fw, all_policies); findBranchesInMangleTable(fw, all_policies); findImportedRuleSets(fw, all_nat); try { AutomaticRules_ipt auto_rules(fw, persistent_objects); auto_rules.addConntrackRule(); auto_rules.addFailoverRules(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() assignUniqueRuleIds(all_policies); assignUniqueRuleIds(all_nat); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); /* clear chain tracker map only between ipv4/ipv6 runs Don't clear it between compiler runs for different policy or nat objects for the same address family. */ minus_n_commands_filter.clear(); minus_n_commands_mangle.clear(); minus_n_commands_nat.clear(); /* We need to create and run preprocessor for this address family before nat and policy compilers, but if there are no nat / policy rules for this address family, we do not need preprocessor either. */ // Count rules for each address family int nat_count = 0; int policy_count = 0; for (list<FWObject*>::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (nat->matchingAddressFamily(policy_af)) nat_count++; } for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (nat_count || policy_count) { Preprocessor_ipt* prep = new Preprocessor_ipt( objdb , fw, ipv6_policy); prep->setSingleRuleCompileMode(single_rule_id); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); delete prep; } ostringstream automaitc_rules_stream; ostringstream automaitc_mangle_stream; ostringstream filter_rules_stream; ostringstream mangle_rules_stream; ostringstream nat_rules_stream; bool empty_output = true; // First, process branch NAT rulesets, then top NAT ruleset NAT *top_nat = NULL; for (list<FWObject*>::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (!nat->matchingAddressFamily(policy_af)) continue; if (nat->isTop()) { top_nat = nat; continue; } if (! processNatRuleSet( fw, nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; } if (top_nat && ! processNatRuleSet( fw, top_nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; // first process all non-top rule sets, then all top rule sets for (int all_top = 0; all_top < 2; ++all_top) { for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) continue; if (policy->isTop() && all_top == 0) continue; if (!policy->isTop() && all_top == 1) continue; if (! processPolicyRuleSet( fw, policy, single_rule_id, filter_rules_stream, mangle_rules_stream, automaitc_rules_stream, automaitc_mangle_stream, oscnf.get(), policy_af, minus_n_commands_filter, minus_n_commands_mangle)) empty_output = false; } } if (!empty_output && !single_rule_compile_on) { if (ipv6_policy) { have_ipv6 = true; generated_script += "\n\n"; generated_script += "# ================ IPv6\n"; generated_script += "\n\n"; } else { have_ipv4 = true; generated_script += "\n\n"; generated_script += "# ================ IPv4\n"; generated_script += "\n\n"; } } generated_script += dumpScript(fw, automaitc_rules_stream.str(), automaitc_mangle_stream.str(), nat_rules_stream.str(), mangle_rules_stream.str(), filter_rules_stream.str(), ipv6_policy); if (single_rule_compile_on) generated_script += "\n\n"; } std::auto_ptr<RoutingCompiler_ipt> routing_compiler( new RoutingCompiler_ipt(objdb, fw, false, oscnf.get())); RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing_compiler->setSourceRuleSet(routing); routing_compiler->setRuleSetName(routing->getName()); routing_compiler->setPersistentObjects(persistent_objects); routing_compiler->setSingleRuleCompileMode(single_rule_id); routing_compiler->setDebugLevel( dl ); if (rule_debug_on) routing_compiler->setDebugRule(drr); routing_compiler->setVerbose( verbose ); if (inTestMode()) routing_compiler->setTestMode(); if (inEmbeddedMode()) routing_compiler->setEmbeddedMode(); if ( (routing_rules_count=routing_compiler->prolog()) > 0 ) { routing_compiler->compile(); routing_compiler->epilog(); } if (routing_compiler->haveErrorsAndWarnings()) all_errors.push_back(routing_compiler->getErrors("").c_str()); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (getErrors("") + generated_script + routing_compiler->getCompiledScript()).c_str())); } /* * These store generated configuration internally, extract it later using * OSConfiguration::getGeneratedFiles(); */ oscnf->processFirewallOptions(); /* * now write generated scripts to files */ char *timestr = NULL; time_t tm; struct tm *stm; tm = time(NULL); stm = localtime(&tm); timestr = strdup(ctime(&tm)); timestr[strlen(timestr)-1] = '\0'; /* * assemble the script and then perhaps post-process it if it * should run on Linksys device with sveasoft firmware */ Configlet script_skeleton(fw, "linux24", "script_skeleton"); script_skeleton.removeComments(); QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); /* * text comes from the compiler in UTF-8 (because all comments * and object names are stored in UTF-8 in objects and * compilers do not decode). We have a choice: 1) apply * QString::fromUtf8() to all strings coming from the compiler * to convert to Unicode and rely on QTextStream to convert * back to UTF-8 in the generated file, or 2) leavle strings * coming from compilers as-is and tell the stream to not * covert. */ script_buffer = ""; script_skeleton.setVariable("shell_debug", shell_dbg); script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n"; script << "export PATH" << "\n"; script_skeleton.setVariable("path", script_buffer); script_buffer = ""; Configlet script_constants(fw, "linux24", "constants"); script_skeleton.setVariable("constants", script_constants.expand()); /* * print definitions for variables IPTABLES, IP, LOGGER. Some * day we may add a choice of os_variant in the GUI. Right now * paths are either default for a given os_variant, or custom * strings entered by user in the GUI and stored in firewall * options. */ script_skeleton.setVariable("tools", oscnf->printPathForAllTools(os_variant).c_str()); script_skeleton.setVariable("shell_functions", oscnf->printShellFunctions(have_ipv6).c_str()); script_skeleton.setVariable("run_time_address_tables", oscnf->printRunTimeAddressTablesCode().c_str()); script_skeleton.setVariable("using_ipset", oscnf->usingIpSetModule()); if (supports_prolog_epilog) { //script_skeleton.setVariable("prolog_epilog", // oscnf->printPrologEpilogFunctions().c_str()); script_skeleton.setVariable( "prolog_script", fw->getOptionsObject()->getStr("prolog_script").c_str()); script_skeleton.setVariable( "epilog_script", fw->getOptionsObject()->getStr("epilog_script").c_str()); } ostringstream ostr; ostr << "# Configure interfaces" << endl; if ( options->getBool("configure_bonding_interfaces") ) ostr << oscnf->printBondingInterfaceConfigurationCommands(); if ( options->getBool("configure_vlan_interfaces")) ostr << oscnf->printVlanInterfaceConfigurationCommands(); if ( options->getBool("configure_bridge_interfaces") ) ostr << oscnf->printBridgeInterfaceConfigurationCommands(); if ( options->getBool("configure_interfaces") || options->getBool("manage_virtual_addr")) { if ( options->getBool("configure_interfaces")) ostr << oscnf->printInterfaceConfigurationCommands(); else ostr << oscnf->printVirtualAddressesForNatCommands(); } ostr << oscnf->printCommandsToClearKnownInterfaces(); ostr << oscnf->printDynamicAddressesConfigurationCommands(); script_skeleton.setVariable( "configure_interfaces", indent(4, QString(ostr.str().c_str()))); // verify_interfaces checks bridge interfaces so run it // after those have been created if (options->getBool("verify_interfaces")) { list<FWObject*> l2=fw->getByType(Interface::TYPENAME); if (l2.empty() ) script_skeleton.setVariable("verify_interfaces", QString()); else script_skeleton.setVariable("verify_interfaces", oscnf->printVerifyInterfacesCommands().c_str()); } else script_skeleton.setVariable("verify_interfaces", QString()); string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); if (prolog_place == "") prolog_place="top"; /* there is no way to stick prolog commands between iptables * reset and iptables rules if we use iptables-restore to * activate policy. Therefore, if prolog needs to be ran after * iptables flush and we use iptables-restore, we run prolog * on top of the script. */ if (!prolog_done && (prolog_place == "top" || (prolog_place == "after_flush" && fw->getOptionsObject()->getBool("use_iptables_restore")))) { script_skeleton.setVariable("prolog_top", 1); script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_flush", 0); prolog_done = true; } if (!prolog_done && prolog_place == "after_interfaces") { script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_after_interfaces", 1); script_skeleton.setVariable("prolog_after_flush", 0); prolog_done = true; } if (!prolog_done && prolog_place == "after_flush") { script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_flush", 1); prolog_done = true; } script_skeleton.setVariable("load_modules", oscnf->generateCodeForProtocolHandlers().c_str()); script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"nat":""); script_skeleton.setVariable("load_modules_with_ipv6", (have_ipv6)?"ipv6":""); script_skeleton.setVariable("ip_forward_commands", oscnf->printIPForwardingCommands().c_str()); /* * script body begins here */ script_buffer = ""; if (oscnf->haveErrorsAndWarnings()) { all_errors.push_back(oscnf->getErrors("").c_str()); } // convert from UTF8 to make sure localized comments are shown correctly // script << oscnf->getCompiledScript().c_str(); // script << generated_script.c_str(); // script << routing_compiler->getCompiledScript().c_str(); script << QString::fromUtf8(oscnf->getCompiledScript().c_str()); script << QString::fromUtf8(generated_script.c_str()); script << QString::fromUtf8(routing_compiler->getCompiledScript().c_str()); script << endl; script_skeleton.setVariable("script_body", indent(4, script_buffer)); script_skeleton.setVariable("timestamp", timestr); script_skeleton.setVariable("tz", tzname[stm->tm_isdst]); script_skeleton.setVariable("user", user_name); script_skeleton.setVariable("database", objdb->getFileName().c_str()); /* * Call reset_all function to flush and reset iptables, but only * do this if we do not use iptables_restore. Reset is done as part * of iptables-restore script in the latter case and commands are * added in PolicyCompiler_ipt::flushAndSetDefaultPolicy() */ script_skeleton.setVariable("not_using_iptables_restore", ! fw->getOptionsObject()->getBool("use_iptables_restore")); script_buffer = ""; if (have_ipv4) script << " reset_iptables_v4" << endl; if (have_ipv6) script << " reset_iptables_v6" << endl; script_skeleton.setVariable("reset_all", script_buffer); script_buffer = ""; Configlet block_action(fw, "linux24", "block_action"); if (XMLTools::version_compare(fw_version, "1.4.20") >= 0) block_action.setVariable("opt_wait", "-w"); else block_action.setVariable("opt_wait", ""); block_action.collapseEmptyStrings(true); // the name of the option is historical (including the typo) if (fw->getOptionsObject()->getBool("add_mgmt_ssh_rule_when_stoped")) { std::auto_ptr<PolicyCompiler_ipt> policy_compiler = createPolicyCompiler(fw, false, NULL, NULL); PolicyCompiler_ipt::PrintRule* print_rule = policy_compiler->createPrintRuleProcessor(); print_rule->setContext(policy_compiler.get()); print_rule->_printBackupSSHAccessRules(&block_action); } else { block_action.setVariable("mgmt_access", 0); } script_skeleton.setVariable("block_action", block_action.expand()); Configlet stop_action(fw, "linux24", "stop_action"); stop_action.collapseEmptyStrings(true); stop_action.setVariable("have_ipv4", have_ipv4); stop_action.setVariable("have_ipv6", have_ipv6); if (XMLTools::version_compare(fw_version, "1.4.20") >= 0) stop_action.setVariable("opt_wait", "-w"); else stop_action.setVariable("opt_wait", ""); script_skeleton.setVariable("stop_action", stop_action.expand()); Configlet status_action(fw, "linux24", "status_action"); status_action.collapseEmptyStrings(true); script_skeleton.setVariable("status_action", status_action.expand()); Configlet top_comment(fw, "linux24", "top_comment"); top_comment.setVariable("version", VERSION); top_comment.setVariable("timestamp", timestr); top_comment.setVariable("tz", tzname[stm->tm_isdst]); top_comment.setVariable("user", user_name); top_comment.setVariable("database", objdb->getFileName().c_str()); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("script_name_on_firewall")); script_buffer = ""; script << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]); if (!remote_file_names[FW_FILE].isEmpty()) script << " " << this->escapeFileName(remote_file_names[FW_FILE]); script << "\n"; /* Add additional files to manifest if specified. Currently there * are no GUI controls to let user provide alternative names for * these on the firewall. See description of manifest format in * comments in src/gui/FirewallInstaller.cpp */ map<string, string> file_list = oscnf->getGeneratedFiles(); if (!file_list.empty()) { info(" Adding additional files to manifest"); map<string, string>::const_iterator c_iter = file_list.begin(); for (; c_iter != file_list.end(); ++c_iter) { string name = c_iter->first; string dest = c_iter->second; script << MANIFEST_MARKER << this->escapeFileName(name.c_str()); if (!dest.empty()) script << " " << dest; script << "\n"; } } top_comment.setVariable("manifest", script_buffer); top_comment.setVariable("platform", platform.c_str()); top_comment.setVariable("fw_version", fw_version.c_str()); top_comment.setVariable("comment", prepend("# ", fw->getComment().c_str())); script_skeleton.setVariable("top_comment", top_comment.expand()); script_skeleton.setVariable("errors_and_warnings", prepend("# ", all_errors.join("\n"))); info("Output file name: " + file_names[FW_FILE].toStdString()); QFile fw_file(file_names[FW_FILE]); if (fw_file.open(QIODevice::WriteOnly)) { QTextStream fw_str(&fw_file); fw_str << script_skeleton.expand(); fw_file.close(); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther | QFile::ExeOwner | QFile::ExeGroup | QFile::ExeOther ); info(" Compiled successfully"); } else { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } free(timestr); if (!all_errors.isEmpty()) status = BaseCompiler::FWCOMPILER_WARNING; } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; }
int main(int argc, char** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; master::Flags flags; // The following flags are executable specific (e.g., since we only // have one instance of libprocess per execution, we only want to // advertise the IP and port option once, here). Option<string> ip; flags.add(&ip, "ip", "IP address to listen on"); uint16_t port; flags.add(&port, "port", "Port to listen on", MasterInfo().port()); Option<string> zk; flags.add(&zk, "zk", "ZooKeeper URL (used for leader election amongst masters)\n" "May be one of:\n" " zk://host1:port1,host2:port2,.../path\n" " zk://username:password@host1:port1,host2:port2,.../path\n" " file:///path/to/file (where file contains one of the above)"); Try<Nothing> load = flags.load("MESOS_", argc, argv); if (load.isError()) { cerr << flags.usage(load.error()) << endl; return EXIT_FAILURE; } if (flags.version) { version(); return EXIT_SUCCESS; } if (flags.help) { cout << flags.usage() << endl; return EXIT_SUCCESS; } // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); } } // Initialize hooks. if (flags.hooks.isSome()) { Try<Nothing> result = HookManager::initialize(flags.hooks.get()); if (result.isError()) { EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error(); } } // Initialize libprocess. if (ip.isSome()) { os::setenv("LIBPROCESS_IP", ip.get()); } os::setenv("LIBPROCESS_PORT", stringify(port)); process::initialize("master"); logging::initialize(argv[0], flags, true); // Catch signals. LOG(INFO) << "Build: " << build::DATE << " by " << build::USER; LOG(INFO) << "Version: " << MESOS_VERSION; if (build::GIT_TAG.isSome()) { LOG(INFO) << "Git tag: " << build::GIT_TAG.get(); } if (build::GIT_SHA.isSome()) { LOG(INFO) << "Git SHA: " << build::GIT_SHA.get(); } // Create an instance of allocator. const std::string allocatorName = flags.allocator; Try<Allocator*> allocator = Allocator::create(allocatorName); if (allocator.isError()) { EXIT(EXIT_FAILURE) << "Failed to create '" << allocatorName << "' allocator: " << allocator.error(); } CHECK_NOTNULL(allocator.get()); LOG(INFO) << "Using '" << allocatorName << "' allocator"; state::Storage* storage = NULL; Log* log = NULL; if (flags.registry == "in_memory") { if (flags.registry_strict) { EXIT(EXIT_FAILURE) << "Cannot use '--registry_strict' when using in-memory storage" << " based registry"; } storage = new state::InMemoryStorage(); } else if (flags.registry == "replicated_log" || flags.registry == "log_storage") { // TODO(bmahler): "log_storage" is present for backwards // compatibility, can be removed before 0.19.0. if (flags.work_dir.isNone()) { EXIT(EXIT_FAILURE) << "--work_dir needed for replicated log based registry"; } Try<Nothing> mkdir = os::mkdir(flags.work_dir.get()); if (mkdir.isError()) { EXIT(EXIT_FAILURE) << "Failed to create work directory '" << flags.work_dir.get() << "': " << mkdir.error(); } if (zk.isSome()) { // Use replicated log with ZooKeeper. if (flags.quorum.isNone()) { EXIT(EXIT_FAILURE) << "Need to specify --quorum for replicated log based" << " registry when using ZooKeeper"; } Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get()); if (url.isError()) { EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error(); } log = new Log( flags.quorum.get(), path::join(flags.work_dir.get(), "replicated_log"), url.get().servers, flags.zk_session_timeout, path::join(url.get().path, "log_replicas"), url.get().authentication, flags.log_auto_initialize); } else { // Use replicated log without ZooKeeper. log = new Log( 1, path::join(flags.work_dir.get(), "replicated_log"), set<UPID>(), flags.log_auto_initialize); } storage = new state::LogStorage(log); } else { EXIT(EXIT_FAILURE) << "'" << flags.registry << "' is not a supported" << " option for registry persistence"; } CHECK_NOTNULL(storage); state::protobuf::State* state = new state::protobuf::State(storage); Registrar* registrar = new Registrar(flags, state); Repairer* repairer = new Repairer(); Files files; MasterContender* contender; MasterDetector* detector; // TODO(vinod): 'MasterContender::create()' should take // Option<string>. Try<MasterContender*> contender_ = MasterContender::create(zk.get("")); if (contender_.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master contender: " << contender_.error(); } contender = contender_.get(); // TODO(vinod): 'MasterDetector::create()' should take // Option<string>. Try<MasterDetector*> detector_ = MasterDetector::create(zk.get("")); if (detector_.isError()) { EXIT(EXIT_FAILURE) << "Failed to create a master detector: " << detector_.error(); } detector = detector_.get(); Option<Authorizer*> authorizer = None(); if (flags.acls.isSome()) { Try<Owned<Authorizer>> create = Authorizer::create(flags.acls.get()); if (create.isError()) { EXIT(EXIT_FAILURE) << "Failed to initialize the authorizer: " << create.error() << " (see --acls flag)"; } // Now pull out the authorizer but need to make a copy since we // get a 'const &' from 'Try::get'. authorizer = Owned<Authorizer>(create.get()).release(); } Option<shared_ptr<RateLimiter>> slaveRemovalLimiter = None(); if (flags.slave_removal_rate_limit.isSome()) { // Parse the flag value. // TODO(vinod): Move this parsing logic to flags once we have a // 'Rate' abstraction in stout. vector<string> tokens = strings::tokenize(flags.slave_removal_rate_limit.get(), "/"); if (tokens.size() != 2) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>"; } Try<int> permits = numify<int>(tokens[0]); if (permits.isError()) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>" << ": " << permits.error(); } Try<Duration> duration = Duration::parse(tokens[1]); if (duration.isError()) { EXIT(EXIT_FAILURE) << "Invalid slave_removal_rate_limit: " << flags.slave_removal_rate_limit.get() << ". Format is <Number of slaves>/<Duration>" << ": " << duration.error(); } slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get()); } if (flags.firewall_rules.isSome()) { vector<Owned<FirewallRule>> rules; const Firewall firewall = flags.firewall_rules.get(); if (firewall.has_disabled_endpoints()) { hashset<string> paths; foreach (const string& path, firewall.disabled_endpoints().paths()) { paths.insert(path); } rules.emplace_back(new DisabledEndpointsFirewallRule(paths)); }
void instDialog::setFlags(QTreeWidgetItem* item) { int obj_id = item->data(0, Qt::UserRole).toInt(); Firewall *fw = Firewall::cast(project->db()->findInIndex(obj_id)); QTreeWidgetItem* parent = item->parent(); time_t lm = fw->getInt("lastModified"); time_t lc = fw->getInt("lastCompiled"); time_t li = fw->getInt("lastInstalled"); QDateTime dt; if (fwbdebug) { qDebug() << "instDialog::setFlags" << item->text(0) << "parent=" << parent << "fw=" << fw << "Firewall::isA(fw)=" << Firewall::isA(fw) << "lm=" << lm << "lc=" << lc << "li=" << li << "compile_only=" << compile_only; qDebug() << "fw->needsCompile()" << fw->needsCompile() << "checkIfNeedToCompile(fw)=" << checkIfNeedToCompile(fw); } // need to skip the secondary cluster members if platform only // allows installations on the primary (e.g. PIX). Note that // platform attribute must be the same in the cluster and member // firewalls objects. See #998 string platform = fw->getStr("platform"); bool install_only_on_primary_member = Resources::getTargetCapabilityBool( platform, "install_only_on_primary"); Cluster *cluster = NULL; FWObject *master_interface = NULL; if (parent) { int obj_id = parent->data(0, Qt::UserRole).toInt(); cluster = Cluster::cast(project->db()->findInIndex(obj_id)); if (cluster) { FWObject *state_sync_group = cluster->getFirstByType(StateSyncClusterGroup::TYPENAME); // use state sync group to find which member firewall is // master. This is only needed for platforms that install // only on master (PIX at this time) if (state_sync_group) { string master_id = state_sync_group->getStr("master_iface"); for (FWObjectTypedChildIterator grp_it = state_sync_group->findByType(FWObjectReference::TYPENAME); grp_it != grp_it.end(); ++grp_it) { FWObject *iface = FWObjectReference::getObject(*grp_it); if (FWObjectDatabase::getStringId(iface->getId()) == master_id) { master_interface = iface; break; } } } } } // Real firewalls get checkbox for install if (Firewall::isA(fw)) { bool checked = false; if (!compile_only) { checked = checkIfNeedToInstall(fw); if (cluster) { // override if checkIfNeedToCompile() is true for the // parent cluster. if (checkIfNeedToCompile(cluster)) { checked = true; } } item->setCheckState(INSTALL_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); // If this platform requires installation only on // the master, disable and uncheck checkbox for the standby. if (install_only_on_primary_member && master_interface != NULL) { QString txt = item->text(0); if (master_interface->isChildOf(fw)) { // Master item->setText(0, QString("%1 (master)").arg(txt)); } else { // Standby item->setText(0, QString("%1 (standby)").arg(txt)); item->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked); item->setFlags(0); } } } if (cluster==NULL) { // we are adding firewall that is not cluster member, it // needs "compile" checkbox checked = checkIfNeedToCompile(fw); item->setCheckState(COMPILE_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); } } int num_members = 0; // Clusters only get checkbox for compile, and only if they have members. if (Cluster::isA(fw)) { list<Firewall*> members; Cluster::cast(fw)->getMembersList(members); num_members = members.size(); if (num_members) { bool checked = checkIfNeedToCompile(fw); item->setCheckState(COMPILE_CHECKBOX_COLUMN, checked?Qt::Checked:Qt::Unchecked); } } dt.setTime_t(lm); item->setText(LAST_MODIFIED_COLUMN, (lm)?dt.toString():QString("Never")); dt.setTime_t(lc); item->setText(LAST_COMPILED_COLUMN, (lc)?dt.toString():QString("Never")); dt.setTime_t(li); item->setText(LAST_INSTALLED_COLUMN, (li)?dt.toString():QString("Never")); }