/** * Copyright (c) 2009--2014 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.manager.kickstart; import com.redhat.rhn.common.conf.ConfigDefaults; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.db.datasource.ModeFactory; import com.redhat.rhn.common.db.datasource.SelectMode; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.util.download.DownloadException; import com.redhat.rhn.common.util.download.DownloadUtils; import com.redhat.rhn.common.validator.ValidatorException; import com.redhat.rhn.domain.kickstart.KickstartData; import com.redhat.rhn.domain.kickstart.KickstartFactory; import com.redhat.rhn.domain.kickstart.KickstartIpRange; import com.redhat.rhn.domain.kickstart.KickstartableTree; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.server.NetworkInterface; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.SystemOverview; import com.redhat.rhn.frontend.dto.kickstart.KickstartIpRangeDto; import com.redhat.rhn.manager.BaseManager; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * * KickstartManager * @version $Rev$ */ public class KickstartManager extends BaseManager { private static final KickstartManager INSTANCE = new KickstartManager(); /** * Returns an instance of kickstart manager * @return an instance */ public static KickstartManager getInstance() { return INSTANCE; } /** * Render the kickstart using cobbler and return the contents with the Cobbler host * search/replaced. * * @param host the host to force into the ks file. searches and replaces all * instances of the Cobbler Host with whatever you pass in. Use with Proxies. * @param data the KickstartData * @return the rendered kickstart contents */ public String renderKickstart(String host, KickstartData data) { return renderKickstart(host, KickstartUrlHelper.getCobblerProfileUrl(data)); } /** * Render the kickstart using cobbler and return the contents with the Cobbler host * search/replaced. * * @param host the host to force into the ks file. searches and replaces all * instances of the Cobbler Host with whatever you pass in. Use with Proxies. * @param url The url to fetch * @return the rendered kickstart contents */ public String renderKickstart(String host, String url) { String retval = renderKickstart(url); // Search/replacing all instances of cobbler host with host // we pass in, for use with Spacewalk Proxy. retval = retval.replaceAll(ConfigDefaults.get().getCobblerHost(), host); return retval; } /** * Render the kickstart using cobbler and return the contents * @param data the KickstartData * @return the rendered kickstart contents */ public String renderKickstart(KickstartData data) { return renderKickstart(KickstartUrlHelper.getCobblerProfileUrl(data)); } /** * Render the kickstart using cobbler and return the contents * @param url the url to fetch * @return the rendered kickstart contents */ public String renderKickstart(String url) { return DownloadUtils.downloadUrl(url); } /** * Simple method to validate a generated kickstart * @param ksdata the kickstart data file whose ks * templates will be checked * @throws ValidatorException on parse error or ISE.. */ public void validateKickstartFile(KickstartData ksdata) { try { if (ksdata.isValid()) { String text = renderKickstart(ksdata); if (text.contains("Traceback (most recent call last):") || text.contains("There is a templating error preventing this file from")) { ValidatorException. raiseException("kickstart.jsp.error.template_generation", LocalizationService.getInstance(). getMessage("kickstartdownload.jsp.header")); } } } catch (DownloadException de) { ValidatorException.raiseException("kickstart.jsp.error.template_generation", LocalizationService.getInstance().getMessage("kickstartdownload.jsp.header")); } } /** * returns a list of systems in SSM * that are kickstartable * @param user the user for access info * @return the list of kickstartable systems */ public DataResult<SystemOverview> kickstartableSystemsInSsm(User user) { SelectMode m = ModeFactory.getMode("System_queries", "ssm_kickstartable"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); return makeDataResult(params, Collections.EMPTY_MAP, null, m); } /** * returns a list of IP ranges accessible to the * user * @param user the current user needed for org information * @return the the list of ip ranges accessible to the user. */ public List<KickstartIpRange> listIpRanges(User user) { return KickstartFactory.lookupRangeByOrg(user.getOrg()); } /** * Find a kickstart profile for a given server by searching by IP addresses * @param server the server to find the ksdata for * @return the kickstartData or 'null' if nothing found */ public KickstartData findProfileForServersNetwork(Server server) { KickstartData ks = null; /* * So first get the IP address for eth0 and see if there's * A kickstart that corresponds to it */ NetworkInterface nic = server.getNetworkInterface("eth0"); if (nic != null && nic.isPublic()) { IpAddress ip = new IpAddress(nic.getIpaddr()); ks = findProfileForIpAddress(ip, server.getOrg()); } /* * If there wasn't, then lets just take the first good ip address we can find */ if (ks == null) { for (NetworkInterface tmp : server.getNetworkInterfaces()) { if (tmp.isPublic()) { IpAddress ip = new IpAddress(tmp.getIpaddr()); ks = findProfileForIpAddress(ip, server.getOrg()); if (ks != null) { break; } } } } return ks; } /** * Finds the profile which is a best fit. * @param clientIpIn IpAddress to search ip ranges for * @param orgIn Org coming in from the url * @return best KickstartData Profile */ public KickstartData findProfileForIpAddress(IpAddress clientIpIn, Org orgIn) { DataResult ipRanges = null; SelectMode mode = ModeFactory.getMode("General_queries", "org_ks_ip_ranges_for_ip"); Map<String, Object> params = new HashMap<String, Object>(); params.put("org_id", orgIn.getId()); params.put("ip", clientIpIn.getLongNumber()); ipRanges = mode.execute(params); IpAddressRange bestRange = null; // find innermost range and return profile for (Iterator itr = ipRanges.iterator(); itr.hasNext();) { KickstartIpRangeDto range = (KickstartIpRangeDto)itr.next(); IpAddressRange iprange = new IpAddressRange(range.getMin().longValue(), range.getMax().longValue(), range.getId().longValue()); //seed range if null bestRange = (bestRange == null) ? iprange : bestRange; if (iprange.isSubset(bestRange)) { bestRange = iprange; } } return (bestRange == null) ? KickstartFactory.lookupOrgDefault(orgIn) : KickstartFactory.lookupKickstartDataByIdAndOrg(orgIn, bestRange.getKsid()); } /** * Accept a list of trees and only return those * that are valid, as in they pass the isValid method * @param trees the input list * @return List of KickstartableTree objects */ public List<KickstartableTree> removeInvalid(List<KickstartableTree> trees) { List<KickstartableTree> ret = new LinkedList<KickstartableTree>(trees); for (Iterator<KickstartableTree> itr = ret.iterator(); itr.hasNext();) { KickstartableTree tree = itr.next(); if (!tree.isValid()) { itr.remove(); } } return ret; } }