/**
* Copyright (c) 2009--2015 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.domain.server;
import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.domain.BaseDomainHelper;
import com.redhat.rhn.domain.Identifiable;
import com.redhat.rhn.domain.channel.Channel;
import com.redhat.rhn.domain.common.ProvisionState;
import com.redhat.rhn.domain.config.ConfigChannel;
import com.redhat.rhn.domain.config.ConfigChannelListProcessor;
import com.redhat.rhn.domain.config.ConfigChannelType;
import com.redhat.rhn.domain.config.ConfigurationFactory;
import com.redhat.rhn.domain.entitlement.Entitlement;
import com.redhat.rhn.domain.entitlement.VirtualizationEntitlement;
import com.redhat.rhn.domain.org.CustomDataKey;
import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.org.OrgFactory;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.manager.configuration.ConfigurationManager;
import com.redhat.rhn.manager.entitlement.EntitlementManager;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper;
import com.redhat.rhn.manager.system.SystemManager;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.cobbler.CobblerConnection;
import org.cobbler.SystemRecord;
import java.net.IDN;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* Server - Class representation of the table rhnServer.
*
* @version $Rev$
*/
public class Server extends BaseDomainHelper implements Identifiable {
/**
* Logger for this class
*/
private static Logger log = Logger.getLogger(Server.class);
private Boolean ignoreEntitlementsForMigration;
private Long id;
private Org org;
private String digitalServerId;
private String os;
private String release;
private String name;
private String description;
private String info;
private String secret;
private User creator;
private String autoUpdate;
private String runningKernel;
private Long lastBoot;
private ServerArch serverArch;
private ProvisionState provisionState;
private Date channelsChanged;
private Date created;
private String cobblerId;
private Set<Device> devices;
private ServerInfo serverInfo;
private CPU cpu;
private ServerLock lock;
private ServerUuid serverUuid;
private Set<Note> notes;
private Set<Network> networks;
private Ram ram;
private Dmi dmi;
private NetworkInterface primaryInterface;
private Set<NetworkInterface> networkInterfaces;
private Set<CustomDataValue> customDataValues;
private Set<Channel> channels;
private List<ConfigChannel> configChannels = new ArrayList<ConfigChannel>();
private Set<ConfigChannel> localChannels = new HashSet<ConfigChannel>();
private Location serverLocation;
private Set<VirtualInstance> guests = new HashSet<VirtualInstance>();
private VirtualInstance virtualInstance;
private PushClient pushClient;
private final ConfigChannelListProcessor configListProc =
new ConfigChannelListProcessor();
private Set<ServerHistoryEvent> history;
private Set<InstalledPackage> packages;
private ProxyInfo proxyInfo;
private Set<? extends ServerGroup> groups;
private Set<Capability> capabilities;
private CrashCount crashCount;
private Set<Crash> crashes;
public static final String VALID_CNAMES = "valid_cnames_";
/**
* @return Returns the capabilities.
*/
public Set<Capability> getCapabilities() {
return capabilities;
}
/**
* @param capabilitiesIn The capabilities to set.
*/
public void setCapabilities(Set<Capability> capabilitiesIn) {
capabilities = capabilitiesIn;
}
/**
* @return Returns the groups.
*/
protected Set<? extends ServerGroup> getGroups() {
return groups;
}
/**
* @param groupsIn The groups to set.
*/
protected void setGroups(Set<? extends ServerGroup> groupsIn) {
groups = groupsIn;
}
/**
* @return the proxyInfo
*/
public ProxyInfo getProxyInfo() {
return proxyInfo;
}
/**
* the proxy information to set
* @param proxy the proxyInfo to set
*/
public void setProxyInfo(ProxyInfo proxy) {
this.proxyInfo = proxy;
}
/**
* Retrieves the local override channel associated with this system.
* @return the Local Override Channel or create one if none exists
*/
public ConfigChannel getLocalOverride() {
return findLocal(ConfigChannelType.local());
}
/**
* Retrieves the local override channel associated with this system.
* @return the Local Override Channel or NULL if there's none created yet
*/
public ConfigChannel getLocalOverrideNoCreate() {
ensureConfigManageable();
ConfigChannel channel = null;
for (Iterator<ConfigChannel> itr = localChannels.iterator(); itr
.hasNext();) {
ConfigChannel ch = itr.next();
if (ch.getConfigChannelType().equals(ConfigChannelType.local())) {
channel = ch;
break;
}
}
return channel;
}
/**
*
* @param ch Override channel to set
*/
public void setLocalOverride(ConfigChannel ch) {
setLocalType(ch, ConfigChannelType.local());
}
private void setLocalType(ConfigChannel channel,
ConfigChannelType cct) {
ConfigChannel ch = findLocal(cct);
if (ch != null) {
localChannels.remove(ch);
}
localChannels.add(channel);
}
protected void setLocalChannels(Set<ConfigChannel> chls) {
localChannels = chls;
}
protected Set<ConfigChannel> getLocalChannels() {
return localChannels;
}
/**
* Used for retrieving Local/Sandbox override channels since the process is
* exacly the same. Creates the channel if it does not exist.
* @param cct Config Channel type .. (local or sandbox)
* @return Config channel associated with the given type
*/
private ConfigChannel findLocal(ConfigChannelType cct) {
assert localChannels.size() <= 2 : "More than two local override channels" +
"Associated with this server." +
"There should be NO more than Two" +
" Override Channels associated";
ensureConfigManageable();
for (Iterator<ConfigChannel> itr = localChannels.iterator(); itr
.hasNext();) {
ConfigChannel ch = itr.next();
ConfigChannelType item = ch.getConfigChannelType();
if (cct.equals(item)) {
return ch;
}
}
//We automatically create local config channels, so
//if we didn't find one, we just haven't created it yet.
ConfigChannel channel = ConfigurationFactory.createNewLocalChannel(this, cct);
//TODO: Adding the new channel to the set of local channels should
//happen in the createNewLocalChannel method. However, the way things
//are currently set up, I have to work with the member variable, because using
//accessors and mutators would create an infinite loop. Fix this setup.
localChannels.add(channel);
setLocalChannels(localChannels);
return channel;
}
/**
* Retrieves the sandbox override channel associated with this system.
* @return the Sandbox Override Channel or create one if none exists
*/
public ConfigChannel getSandboxOverride() {
return findLocal(ConfigChannelType.sandbox());
}
/**
* Retrieves the sandbox override channel associated with this system.
* @return the Sandbox Override Channel or NULL if there's none created yet
*/
public ConfigChannel getSandboxOverrideNoCreate() {
ensureConfigManageable();
ConfigChannel channel = null;
for (Iterator<ConfigChannel> itr = localChannels.iterator(); itr
.hasNext();) {
ConfigChannel ch = itr.next();
if (ch.getConfigChannelType().equals(ConfigChannelType.sandbox())) {
channel = ch;
break;
}
}
return channel;
}
/**
*
* @param ch sets the sandbox override channel
*/
public void setSandboxOverride(ConfigChannel ch) {
setLocalType(ch, ConfigChannelType.sandbox());
}
/**
* ONLY TO BE USED FOR/BY HIBERNATE
* @param configChannelsIn The configChannels to set.
*/
protected void setConfigChannelsHibernate(
List<ConfigChannel> configChannelsIn) {
configChannels = configChannelsIn;
for (Iterator<ConfigChannel> itr = configChannels.iterator(); itr
.hasNext();) {
if (itr.next() == null) {
itr.remove();
}
}
}
/**
* ONLY TO BE USED FOR/BY HIBERNATE
*
* @return List of config channels
*/
protected List<ConfigChannel> getConfigChannelsHibernate() {
return configChannels;
}
/**
* @return Returns the ServerConfigChannels mappings currently available
* to the server based on it's entitlements.
*/
public List <ConfigChannel> getConfigChannels() {
ensureConfigManageable();
return getConfigChannelsHibernate();
}
/**
* @return Returns the number of configuration channels associated with
* the server.
*/
public int getConfigChannelCount() {
return getConfigChannelsHibernate().size();
}
private void ensureConfigManageable() {
if (!getIgnoreEntitlementsForMigration()) {
ConfigurationManager.getInstance().ensureConfigManageable(this);
}
}
/**
* subscribes a channel to a system, giving it the
* highest value for the position (or the lowest priority)
* @param cc The config channel to subscribe to
*/
public void subscribe(ConfigChannel cc) {
configListProc.add(getConfigChannels(), cc);
}
/**
* subscribes a channel to a system at the given position
* @param cc the channel to subscribe
* @param position the positon/ranking of the channel in the system list,
* must be > 0
*/
public void subscribeAt(ConfigChannel cc, int position) {
configListProc.add(getConfigChannels(), cc, position);
}
/**
* @param cc the ConfigChannel to unsubscribe
* @return returns true if the remove operation succeeded
*/
public boolean unsubscribe(ConfigChannel cc) {
return configListProc.remove(getConfigChannels(), cc);
}
/**
* Protected constructor
*/
protected Server() {
devices = new HashSet<Device>();
notes = new HashSet<Note>();
networks = new HashSet<Network>();
networkInterfaces = new HashSet<NetworkInterface>();
customDataValues = new HashSet<CustomDataValue>();
ignoreEntitlementsForMigration = Boolean.FALSE;
}
/**
* @return Returns the serverInfo.
*/
public ServerInfo getServerInfo() {
return serverInfo;
}
/**
* @param serverInfoIn The serverInfo to set.
*/
public void setServerInfo(ServerInfo serverInfoIn) {
this.serverInfo = serverInfoIn;
}
/**
* Gets the last checkin date for this server
* @return last checkin date
*/
public Date getLastCheckin() {
return serverInfo.getCheckin();
}
/**
* Gets the number of times this server has checked in
* @return number of times this server has checked in.
*/
public Long getCheckinCount() {
return serverInfo.getCheckinCounter();
}
/**
* Getter for id
*
* @return Long to get
*/
public Long getId() {
return this.id;
}
/**
* Setter for id
*
* @param idIn to set
*/
public void setId(Long idIn) {
this.id = idIn;
}
/**
* @return Returns the org.
*/
public Org getOrg() {
return org;
}
/**
* @param o The org to set.
*/
public void setOrg(Org o) {
this.org = o;
}
/**
* Getter for digitalServerId
*
* @return String to get
*/
public String getDigitalServerId() {
return this.digitalServerId;
}
/**
* Setter for digitalServerId
*
* @param digitalServerIdIn to set
*/
public void setDigitalServerId(String digitalServerIdIn) {
this.digitalServerId = digitalServerIdIn;
}
/**
* Getter for os
*
* @return String to get
*/
public String getOs() {
return this.os;
}
/**
* Setter for os
*
* @param osIn to set
*/
public void setOs(String osIn) {
this.os = osIn;
}
/**
* Getter for release
*
* @return String to get
*/
public String getRelease() {
return this.release;
}
/**
* Setter for release
*
* @param releaseIn to set
*/
public void setRelease(String releaseIn) {
this.release = releaseIn;
}
/**
* Getter for name
*
* @return String to get
*/
public String getName() {
return this.name;
}
/**
* Setter for name
*
* @param nameIn to set
*/
public void setName(String nameIn) {
this.name = nameIn;
}
/**
* Getter for description
*
* @return String to get
*/
public String getDescription() {
return this.description;
}
/**
* Setter for description
*
* @param descriptionIn to set
*/
public void setDescription(String descriptionIn) {
this.description = descriptionIn;
}
/**
* Getter for info
*
* @return String to get
*/
public String getInfo() {
return this.info;
}
/**
* Setter for info
*
* @param infoIn to set
*/
public void setInfo(String infoIn) {
this.info = infoIn;
}
/**
* Getter for secret
*
* @return String to get
*/
public String getSecret() {
return this.secret;
}
/**
* Setter for secret
*
* @param secretIn to set
*/
public void setSecret(String secretIn) {
this.secret = secretIn;
}
/**
* @return Returns the creator.
*/
public User getCreator() {
return creator;
}
/**
* @param c The creator to set.
*/
public void setCreator(User c) {
this.creator = c;
}
/**
* Getter for autoUpdate
*
* @return String to get
*/
public String getAutoUpdate() {
return this.autoUpdate;
}
/**
* Setter for autoUpdate
*
* @param autoUpdateIn to set
*/
public void setAutoUpdate(String autoUpdateIn) {
this.autoUpdate = autoUpdateIn;
}
/**
* Getter for runningKernel
*
* @return String to get
*/
public String getRunningKernel() {
return this.runningKernel;
}
/**
* Setter for runningKernel
*
* @param runningKernelIn to set
*/
public void setRunningKernel(String runningKernelIn) {
this.runningKernel = runningKernelIn;
}
/**
* Getter for lastBoot
*
* @return Long to get
*/
public Long getLastBoot() {
return this.lastBoot;
}
/**
* Getter for lastBoot as a date
*
* @return lastBoot time as a Date object
*/
public Date getLastBootAsDate() {
return new Date(this.lastBoot.longValue() * 1000);
}
/**
* Setter for lastBoot
*
* @param lastBootIn to set
*/
public void setLastBoot(Long lastBootIn) {
this.lastBoot = lastBootIn;
}
/**
* @return Returns the serverArch.
*/
public ServerArch getServerArch() {
return serverArch;
}
/**
* @param s The serverArch to set.
*/
public void setServerArch(ServerArch s) {
this.serverArch = s;
}
/**
* @return Returns the provisionState.
*/
public ProvisionState getProvisionState() {
return provisionState;
}
/**
* @param p The provisionState to set.
*/
public void setProvisionState(ProvisionState p) {
this.provisionState = p;
}
/**
* Getter for channelsChanged
*
* @return Date to get
*/
public Date getChannelsChanged() {
return this.channelsChanged;
}
/**
* Setter for channelsChanged
*
* @param channelsChangedIn to set
*/
public void setChannelsChanged(Date channelsChangedIn) {
this.channelsChanged = channelsChangedIn;
}
/**
* The set of ServerGroup(s) that this Server is a member of
* @return Returns the serverGroups.
*/
public List<EntitlementServerGroup> getEntitledGroups() {
return ServerGroupFactory.listEntitlementGroups(this);
}
/**
* The set of ServerGroup(s) that this Server is a member of
* @return Returns the serverGroups.
*/
public List<ManagedServerGroup> getManagedGroups() {
return ServerGroupFactory.listManagedGroups(this);
}
/**
* Returns the set of devices attached to this server.
* @return Returns the list of devices attached to this server.
*/
public Set<Device> getDevices() {
return devices;
}
/**
* Sets the set of devices.
* @param devicesIn The devices to set.
*/
protected void setDevices(Set<Device> devicesIn) {
devices = devicesIn;
}
/**
* Get the Device with the given description (i.e. eth0)
* @param dev the device name (i.e. sda)
* @return the Device, otherwise null
*/
public Device getDevice(String dev) {
for (Device d : getDevices()) {
if ((d.getDevice() != null) && (d.getDevice().equals(dev))) {
return d;
}
}
return null;
}
/**
* Adds a device to the list of devices for this server.
* @param device Device to add
*/
public void addDevice(Device device) {
device.setServer(this);
devices.add(device);
}
/**
* @return Returns the notes.
*/
public Set<Note> getNotes() {
return notes;
}
/**
* @param n The notes to set.
*/
public void setNotes(Set<Note> n) {
this.notes = n;
}
/**
* Adds a note to the notes set
* @param note The note to add
*/
public void addNote(Note note) {
note.setServer(this);
notes.add(note);
}
/**
* Adds a note to the notes set.
* @param user The user creating the note
* @param subject The subject for the note
* @param body The body for the note
*/
public void addNote(User user, String subject, String body) {
Note note = new Note();
note.setCreator(user);
note.setSubject(subject);
note.setNote(body);
note.setCreated(new Date());
addNote(note);
}
/**
* @return Returns the networks
*/
public Set<Network> getNetworks() {
return networks;
}
/**
* Sets the set of networks
* @param n The networks to set
*/
public void setNetworks(Set<Network> n) {
this.networks = n;
}
/**
* Adds a network to the set of networks for this server.
* @param network The network to add.
*/
public void addNetwork(Network network) {
network.setServer(this);
networks.add(network);
}
/**
* Get the primary ip address for this server
* @return Returns the primary ip for this server
*/
public String getIpAddress() {
Network n = findPrimaryNetwork();
if (n != null) {
log.debug("Found a Network: " + n.getIpaddr());
return n.getIpaddr();
}
NetworkInterface ni = findPrimaryNetworkInterface();
if (ni != null) {
log.debug("Found a NetworkInterface: " + ni.getIpaddr());
return ni.getIpaddr();
}
return null;
}
/**
* Get the primary ipv6 address for this server
* @return Returns the primary ip for this server
*/
public String getIp6Address() {
Network n = findPrimaryIpv6Network();
if (n != null) {
log.debug("Found a Network: " + n.getIp6addr());
return n.getIp6addr();
}
return null;
}
/**
* Return the NetworkInterface which Spacewalk is guessing is
* the primary. Order of preference:
*
* eth0, eth0*, eth1, eth1*, after that its first match that is
* not 127.0.0.1
*
* @return NetworkInterface in order of preference: eth0, eth0*,
* eth1, eth1*, after that its first match that is not 127.0.0.1
*/
public NetworkInterface findPrimaryNetworkInterface() {
primaryInterface = lookupForPrimaryInterface();
if (primaryInterface != null) {
return primaryInterface;
}
if (!networkInterfaces.isEmpty()) {
Iterator<NetworkInterface> i = networkInterfaces.iterator();
// First pass look for names
NetworkInterface ni = null;
ni = findActiveIfaceWithName("eth0", false);
if (ni != null) {
primaryInterface = ni;
return ni;
}
ni = findActiveIfaceWithName("eth0", true);
if (ni != null) {
primaryInterface = ni;
return ni;
}
ni = findActiveIfaceWithName("eth1", false);
if (ni != null) {
primaryInterface = ni;
return ni;
}
ni = findActiveIfaceWithName("eth1", true);
if (ni != null) {
primaryInterface = ni;
return ni;
}
// Second pass look for localhost
i = networkInterfaces.iterator();
while (i.hasNext()) {
NetworkInterface n = i.next();
String addr = n.getIpaddr();
if (addr != null &&
!addr.equals("127.0.0.1")) {
log.debug("Found NetworkInterface !localhost");
primaryInterface = n;
return n;
}
for (ServerNetAddress6 ad6 : n.getIPv6Addresses()) {
if (ad6 != null && !ad6.getAddress().equals("::1")) {
log.debug("Found NetworkInterface !localhost");
primaryInterface = n;
return n;
}
}
}
// If we didnt match any of the above criteria
// just give up and return the 1st one.
log.debug("just returning 1st network interface");
primaryInterface = networkInterfaces.iterator().next();
return primaryInterface;
}
primaryInterface = null;
return null;
}
private NetworkInterface findActiveIfaceWithName(String pattern, boolean startsWith) {
if (networkInterfaces.isEmpty()) {
return null;
}
for (Iterator<NetworkInterface> i = networkInterfaces.iterator(); i
.hasNext();) {
NetworkInterface ni = i.next();
if (ni.isDisabled()) {
continue;
}
if (startsWith) {
if (ni.getName().startsWith(pattern)) {
log.debug("Found " + pattern + "*");
return ni;
}
}
else {
if (ni.getName().equals(pattern)) {
log.debug("Found " + pattern);
return ni;
}
}
}
return null;
}
// Sometimes java really annoys me
private Network findPrimaryNetwork() {
if (!networks.isEmpty()) {
Iterator<Network> i = networks.iterator();
while (i.hasNext()) {
Network n = i.next();
String addr = n.getIpaddr();
if (addr != null &&
!addr.equals("127.0.0.1")) {
log.debug("returning Network that is !localhost");
return n;
}
}
log.debug("giving up, returning 1st Network");
return networks.iterator().next();
}
return null;
}
private Network findPrimaryIpv6Network() {
if (!networks.isEmpty()) {
Iterator<Network> i = networks.iterator();
while (i.hasNext()) {
Network n = i.next();
String addr = n.getIp6addr();
if (addr != null &&
!addr.equals("::1")) {
log.debug("returning Network that is !localhost");
return n;
}
}
log.debug("giving up, returning 1st Network");
return networks.iterator().next();
}
return null;
}
/**
* Get the primary MAC/hardware address for this server
* @return Returns the primary MAC/hardware for this server
*/
public String getHardwareAddress() {
NetworkInterface network = findPrimaryNetworkInterface();
if (network != null) {
return network.getHwaddr();
}
return null;
}
/**
* Get the primary hostname for this server
* @return Returns the primary hostname for this server
*/
public String getHostname() {
if (!networks.isEmpty()) {
Network net = networks.iterator().next();
return net.getHostname();
}
return null;
}
/**
* Get the hostname aliases for this server
* @return Returns the hostname aliases for this server
*/
public List<String> getCnames() {
List<String> result = new ArrayList<String>();
List<String> proxyCnames = Config.get().getList(
VALID_CNAMES +
serverInfo.getId().toString());
if (!proxyCnames.isEmpty()) {
result.addAll(proxyCnames);
}
return result;
}
/**
* Get the primary hostname for this server
* If hostname is IDN, it is decoded from Puny encoding
* @return Returns the primary hostname for this server
*/
public String getDecodedHostname() {
String hostname = getHostname();
return (hostname == null) ? null : IDN.toUnicode(hostname);
}
/**
* Get the hostname aliases (cname records) for this server
* If hostname is IDN, it is decoded from Puny encoding
* @return Returns the primary hostname for this server
*/
public List<String> getDecodedCnames() {
List<String> result = new ArrayList<String>();
for (String hostname : getCnames()) {
result.add(IDN.toUnicode(hostname));
}
return result;
}
/**
* @return Returns the networkInterfaces.
*/
public Set<NetworkInterface> getNetworkInterfaces() {
return networkInterfaces;
}
/**
* @param n The networkInterfaces to set.
*/
public void setNetworkInterfaces(Set<NetworkInterface> n) {
this.networkInterfaces = n;
}
/**
* Adds a network interface to the set of network interfaces
* for this server.
* @param netIn The NetworkInterface to add
*/
public void addNetworkInterface(NetworkInterface netIn) {
netIn.setServer(this);
networkInterfaces.add(netIn);
}
/**
* Returns the total amount of ram for this server.
* @return the total amount of ram for this server.
*/
public long getRam() {
if (ram == null) {
return 0;
}
return ram.getRam();
}
/**
* Convenience method for formatting the Ram as a String value.
* @return String of RAM.
*/
public String getRamString() {
return new Long(getRam()).toString();
}
/**
* the total amount of ram for this server.
* @param ramIn The ram to set.
*/
public void setRam(long ramIn) {
initializeRam();
ram.setRam(ramIn);
}
/**
* Returns the amount of swap for this server.
* @return the amount of swap for this server.
*/
public long getSwap() {
if (ram == null) {
return 0;
}
return ram.getSwap();
}
/**
* the amount of swap for this server.
* @param swapIn the amount of swap for this server.
*/
public void setSwap(long swapIn) {
initializeRam();
ram.setSwap(swapIn);
}
/**
* @return Returns the cpu.
*/
public CPU getCpu() {
return cpu;
}
/**
* @param cpuIn The cpu to set.
*/
public void setCpu(CPU cpuIn) {
this.cpu = cpuIn;
}
/**
* @return Returns the dmi.
*/
public Dmi getDmi() {
return dmi;
}
/**
* @param dmiIn The dmi to set.
*/
public void setDmi(Dmi dmiIn) {
dmi = dmiIn;
}
/**
* @return Returns the serverLocation associated with the server.
*/
public Location getLocation() {
return serverLocation;
}
/**
* @param locationIn Location to associate with the server.
*/
public void setLocation(Location locationIn) {
serverLocation = locationIn;
}
private void initializeRam() {
if (ram == null) {
ram = new Ram();
ram.setServer(this);
}
}
/**
* @return Returns the customDataValues.
*/
public Set<CustomDataValue> getCustomDataValues() {
return customDataValues;
}
/**
* @param customDataValuesIn The customDataValues to set.
*/
public void setCustomDataValues(Set<CustomDataValue> customDataValuesIn) {
this.customDataValues = customDataValuesIn;
}
/**
* Adds a custom data value to the set of custom data values
* for this server.
* @param value The CustomDataValue to add
*/
public void addCustomDataValue(CustomDataValue value) {
value.setServer(this);
customDataValues.add(value);
}
/**
* Adds a custom data value to the set of custom data values
* @param key The CustomDataKey for this value
* @param value The value to set
* @param user The user doing the setting
*/
public void addCustomDataValue(CustomDataKey key, String value, User user) {
// Check for null key values.
if (key == null || key.getLabel() == null) {
throw new
UndefinedCustomDataKeyException("CustomDataKey can not be null.");
}
// Make sure this org has this particular CustomDataKey defined
if (!org.hasCustomDataKey(key.getLabel())) {
throw new
UndefinedCustomDataKeyException("CustomDataKey: " + key.getLabel() +
" is not defined for this org.");
}
// get the CustomDataValue
CustomDataValue customValue = getCustomDataValue(key);
// does the server already have this key defined?
if (customValue == null) {
// create a new CustomDataValue object
customValue = new CustomDataValue();
customValue.setCreator(user);
customValue.setKey(key);
}
customValue.setValue(value);
customValue.setLastModifier(user);
// add customValue to customDataValues set
addCustomDataValue(customValue);
}
/**
* Adds a custom data value to the set of custom data values
* @param keyLabel The label for the CustomDataKey for this value
* @param value The value to set
* @param user The user doing the setting
*/
public void addCustomDataValue(String keyLabel, String value, User user) {
// look up CustomDataKey by keyLabel
CustomDataKey key = OrgFactory.lookupKeyByLabelAndOrg(keyLabel, user.getOrg());
addCustomDataValue(key, value, user);
}
/**
* Retrieves a specific CustomDataValue from the customDataValues set
* @param key The Key for the value you're looking up
* @return Returns a CustomDataValue if it exists for this server. null otherwise.
*/
public CustomDataValue getCustomDataValue(CustomDataKey key) {
return ServerFactory.getCustomDataValue(key, this);
}
/**
* Returns the set of Channels this Server is subscribed to.
* @return the set of Channels this Server is subscribed to.
*/
public Set<Channel> getChannels() {
return channels;
}
protected void setChannels(Set<Channel> chans) {
channels = chans;
}
/**
* Adds the given channel to this Server.
* @param c Channel to be added.
*/
public void addChannel(Channel c) {
channels.add(c);
}
/**
* Returns the base channel for this server or null if not set.
* @return Returns the base channel for this server or null if not set.
*/
public Channel getBaseChannel() {
/*
* The base channel for a given server is designated in the database by
* parent_channel == null. Since the number of channels for a given server is
* relatively small, loop through the channels set and look for one without a
* parentChannel instead of going back to the db.
*/
for (Iterator<Channel> itr = channels.iterator(); itr.hasNext();) {
Channel channel = itr.next();
if (channel.getParentChannel() == null) {
// This is the base channel
return channel;
}
}
// Either we have no channels or all channels have a parent_channel. In either
// case, the base channel cannot be determined for this server.
return null;
}
/**
* Returns true if this is a satellite server.
* @return true if this is a satellite server.
*/
public boolean isSatellite() {
return false;
}
/**
* Returns true if this is a proxy server.
* @return true if this is a proxy server.
*/
public boolean isProxy() {
return getProxyInfo() != null;
}
/**
* Returns true if the server has the given Entitlement.
* @param entitlement Entitlement to verify.
* @return true if the server has the given Entitlement.
*/
public boolean hasEntitlement(Entitlement entitlement) {
List<?> grps = getEntitledGroups();
for (Iterator<?> itr = grps.iterator(); itr.hasNext();) {
ServerGroup g = (ServerGroup) itr.next();
// The server's group type can be null if the user has created some
// custom server groups. If so, we won't check it against the
// given entitlement.
ServerGroupType groupType = g.getGroupType();
if (groupType.getLabel().equals(entitlement.getLabel())) {
return true;
}
}
return false;
}
/**
* Give a set of the entitlements a server has.
* This is entirely based on the server groups, but server
* groups also contain user defined groups.
* @return a set of Entitlement objects
*/
public Set<Entitlement> getEntitlements() {
Set<Entitlement> entitlements = new HashSet<Entitlement>();
Iterator<EntitlementServerGroup> i = getEntitledGroups().iterator();
while (i.hasNext()) {
ServerGroup grp = i.next();
entitlements.add(EntitlementManager.getByName(
grp.getGroupType().getLabel()));
}
return entitlements;
}
/**
* Base entitlement for the Server.
* @return Entitlement that is the base entitlement for the server
*/
public Entitlement getBaseEntitlement() {
Entitlement baseEntitlement = null;
Iterator<EntitlementServerGroup> i = getEntitledGroups().iterator();
while (i.hasNext() && baseEntitlement == null) {
ServerGroupType sgt = (i.next()).getGroupType();
if (sgt.isBase()) {
baseEntitlement = EntitlementManager.getByName(sgt.getLabel());
}
}
return baseEntitlement;
}
/**
* Base entitlement for the Server.
* @param baseIn to update to
*/
public void setBaseEntitlement(Entitlement baseIn) {
ServerGroupType verify = ServerFactory.
lookupServerGroupTypeByLabel(baseIn.getLabel());
if (!verify.isBase()) {
throw new IllegalArgumentException("baseIn is not a base entitlement");
}
Entitlement baseEntitlement = this.getBaseEntitlement();
if (baseEntitlement != null && baseIn.equals(baseEntitlement)) {
// noop if there is no change
return;
}
if (baseEntitlement != null) {
this.getEntitlements().remove(baseEntitlement);
SystemManager.removeServerEntitlement(this.getId(), baseEntitlement);
}
SystemManager.entitleServer(this, baseIn);
}
/**
* Set of add-on entitlements for the Server.
* @return Set of entitlements that are add-on entitlements for the server
*/
public Set<Entitlement> getAddOnEntitlements() {
Set<Entitlement> s = new HashSet<Entitlement>();
Iterator<?> i = getEntitledGroups().iterator();
while (i.hasNext()) {
ServerGroupType sgt = ((ServerGroup) i.next()).getGroupType();
if (!sgt.isBase()) {
s.add(EntitlementManager.getByName(sgt.getLabel()));
}
}
return s;
}
/**
* Returns a comma-delimted list of add-on entitlements with their human readable
* labels.
*
* @return A comma-delimted list of add-on entitlements with their human readable
* labels.
*/
public String getAddOnEntitlementsAsText() {
Set<?> addOnEntitlements = getAddOnEntitlements();
Iterator<?> iterator = addOnEntitlements.iterator();
StringBuilder buffer = new StringBuilder();
Entitlement entitlement = null;
while (iterator.hasNext()) {
entitlement = (Entitlement)iterator.next();
buffer.append(entitlement.getHumanReadableLabel()).append(", ");
}
if (!addOnEntitlements.isEmpty()) {
buffer.delete(buffer.length() - 2, buffer.length());
}
return buffer.toString();
}
/**
* Return <code>true</code> if this is a virtual host, <code>false</code> otherwise.
* If this is a host system, {@link #getVirtualInstance()} will always be <code>null
* </code> since we are not supporting/implementing guests of guest in the RHN 500
* release.
*
* @return true if the system is a virtual host
*/
public boolean isVirtualHost() {
return (SystemManager.isVirtualHost(getOrg().getId(), getId())) ||
hasVirtualizationEntitlement();
}
/**
* Return <code>true</code> if this a guest system, <code>false</code> otherwise. If
* this system is a guest, {@link #getVirtualInstance()} will be non-<code>null</code>.
*
* @return <code>true</code> if this a guest system, <code>false</code> otherwise.
*/
public boolean isVirtualGuest() {
return getVirtualInstance() != null;
}
/**
* Return <code>true</code> if this system has virtualization entitlement,
* <code>false</code> otherwise.
* @return <code>true</code> if this system has virtualization entitlement,
* <code>false</code> otherwise.
*/
public boolean hasVirtualizationEntitlement() {
return hasEntitlement(EntitlementManager.VIRTUALIZATION);
}
/**
*
* @return the virtual guests
*/
private Set<VirtualInstance> getVirtualGuests() {
return guests;
}
private void setVirtualGuests(Set<VirtualInstance> virtualGuests) {
this.guests = virtualGuests;
}
/**
* Returns a read-only collection of VirtualInstance objects.
* @return A read-only collection of VirtualInstance objects.
*/
public Collection<VirtualInstance> getGuests() {
Set<VirtualInstance> retval = new HashSet<VirtualInstance>();
for (VirtualInstance vi : getVirtualGuests()) {
// Filter out the hosts that sometimes show up in this table.
// Hosts have no UUID defined.
if (vi.getUuid() != null) {
retval.add(vi);
}
}
return Collections.unmodifiableCollection(retval);
}
/**
*
* @param guest the guest to add
*/
public void addGuest(VirtualInstance guest) {
guest.setHostSystem(this);
guests.add(guest);
}
/**
* Removes the virtual instance guest from this server. If the guest is registered,
* then the guest server will be deleted from the virtual instance.
*
* @param guest The virtual instance to delete
*
* @return <code>true</code> if the guest is deleted, <code>false</code> otherwise.
*/
public boolean deleteGuest(VirtualInstance guest) {
if (canDeleteGuest(guest)) {
guest.deleteGuestSystem();
return removeGuest(guest);
}
return false;
}
private boolean canDeleteGuest(VirtualInstance guest) {
for (VirtualInstance g : getGuests()) {
if (g.getId().equals(guest.getId())) {
return true;
}
}
return false;
}
/**
* Remove the association between a guest and this server, but do not delete the
* guest server.
*
* @param guest Guest to remove from this server.
* @return <code>true</code> if the guest is deleted, <code>false</code> otherwise.
*/
public boolean removeGuest(VirtualInstance guest) {
boolean deleted = false;
for (Iterator<VirtualInstance> it = guests.iterator(); it.hasNext();) {
VirtualInstance g = it.next();
if (g.getId().equals(guest.getId())) {
guest.setHostSystem(null);
it.remove();
deleted = true;
break;
}
}
return deleted;
}
/**
* Return the virtual instance that owns this server when the server is a virtual guest.
*
* @return The virtual instance that owns this server when the server is a virtual
* guest. If the server is not a guest, the method returns <code>null</code>.
*/
public VirtualInstance getVirtualInstance() {
return virtualInstance;
}
/**
* Sets the owning virtual instance for this server, which effectively makes this a
* guest system.
*
* @param instance The owning virtual instance
*/
// Note that while the relationship between guest and virtual instance needs to be
// bi-directional, we want to manage the relationship (add/delete) from the virtual
// instance since it is the owner/parent. Hence, the reason for package visibility on
// this method.
void setVirtualInstance(VirtualInstance instance) {
virtualInstance = instance;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(final Object other) {
if (other == null || !(other instanceof Server)) {
return false;
}
Server castOther = (Server) other;
return new EqualsBuilder().append(os, castOther.getOs())
.append(release, castOther.getRelease())
.append(name, castOther.getName())
.append(description, castOther.getDescription())
.append(info, castOther.getInfo())
.append(secret, castOther.getSecret())
.append(autoUpdate, castOther.getAutoUpdate())
.append(runningKernel, castOther.getRunningKernel())
.append(lastBoot, castOther.getLastBoot())
.append(channelsChanged, castOther.getChannelsChanged())
.append(getProxyInfo(), castOther.getProxyInfo())
.isEquals();
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return new HashCodeBuilder().append(id).append(digitalServerId).append(os)
.append(release).append(name).append(description)
.append(info).append(secret)
.append(autoUpdate).append(runningKernel)
.append(lastBoot).append(channelsChanged).
append(getProxyInfo())
.toHashCode();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE).append(
"id", id).append("org", org).append("name", name).append(
"description", description).toString();
}
/**
* @return Returns the created.
*/
@Override
public Date getCreated() {
return created;
}
/**
* @param createdIn The created to set.
*/
@Override
public void setCreated(Date createdIn) {
this.created = createdIn;
}
/**
* @return Returns the lock.
*/
public ServerLock getLock() {
return lock;
}
/**
* @param lockIn The lock to set.
*/
public void setLock(ServerLock lockIn) {
this.lock = lockIn;
}
/**
* @return Returns the uuid.
*/
public ServerUuid getServerUuid() {
return this.serverUuid;
}
/**
* @param serverUuidIn The uuid to set.
*/
public void setServerUuid(ServerUuid serverUuidIn) {
this.serverUuid = serverUuidIn;
}
/**
* Business method to check if the system is considered 'inactive'
* @return boolean if it hasn't checked in recently.
*/
public boolean isInactive() {
Date lastCheckin = this.getLastCheckin();
long millisInDay = (1000 * 60 * 60 * 24);
long threshold = Config.get().getInt(ConfigDefaults.SYSTEM_CHECKIN_THRESHOLD, 1);
Date yesterday = new Timestamp(System.currentTimeMillis() -
(millisInDay * threshold));
return lastCheckin.before(yesterday);
}
/**
* Get the Set of Child Channel objects associated with this server. This
* is just a convenience method. Basically the channels associated with this
* server that are not base channels.
*
* @return Set of Child Channels. null of none found.
*/
public Set<Channel> getChildChannels() {
// Make sure we return NULL if none are found
if (this.getChannels() != null) {
Set<Channel> retval = new HashSet<Channel>();
for (Channel c : this.getChannels()) {
// add non base channels (children)
// to return set.
if (!c.isBaseChannel()) {
retval.add(c);
}
}
if (retval.size() == 0) {
return new HashSet<Channel>();
}
return retval;
}
return new HashSet<Channel>();
}
/**
* @return The push client for this server.
*/
public PushClient getPushClient() {
return pushClient;
}
/**
* @param pushClientIn The push client to be used for this server.
*/
public void setPushClient(PushClient pushClientIn) {
this.pushClient = pushClientIn;
}
/**
* Simple check to see if the Server is subscribed to the passed in channel already.
* @param channelIn to check
* @return boolean true false if subbed or not.
*/
public boolean isSubscribed(Channel channelIn) {
Set<Channel> childChannels = this.channels;
if (childChannels != null) {
return childChannels.contains(channelIn);
}
return false;
}
/**
* Check to see if the passed in entitlement can be applied to this server.
* @param entIn to check
* @return boolean if its compatible with this server.
*/
public boolean isEntitlementAllowed(Entitlement entIn) {
// Check virt entitlements.
if (this.isVirtualGuest()) {
if (entIn instanceof VirtualizationEntitlement) {
return false;
}
}
return true;
}
/**
* Get the Set of valid addon Entitlements for this server.
*
* @return Set of valid addon Entitlement instances for this server
*/
public Set<Entitlement> getValidAddonEntitlementsForServer() {
Set<Entitlement> retval = new TreeSet<Entitlement>();
Iterator<?> i = this.getOrg().getValidAddOnEntitlementsForOrg()
.iterator();
while (i.hasNext()) {
Entitlement ent = (Entitlement) i.next();
if (this.isEntitlementAllowed(ent)) {
retval.add(ent);
}
}
return retval;
}
/**
* @return this list of history events for this server
*/
public Set<ServerHistoryEvent> getHistory() {
return history;
}
/**
* Set the history events for this server
* @param historyIn the List of history events
*/
public void setHistory(Set<ServerHistoryEvent> historyIn) {
this.history = historyIn;
}
/**
* @return Returns the packages.
*/
public Set<InstalledPackage> getPackages() {
return packages;
}
/**
* @param packagesIn The packages to set.
*/
public void setPackages(Set<InstalledPackage> packagesIn) {
this.packages = packagesIn;
}
/**
* @return Returns the cobblerId.
*/
public String getCobblerId() {
return cobblerId;
}
/**
* @param cobblerIdIn The cobblerId to set.
*/
public void setCobblerId(String cobblerIdIn) {
this.cobblerId = cobblerIdIn;
}
/**
* @return Returns the ignoreEntitlementsForMigration.
*/
public Boolean getIgnoreEntitlementsForMigration() {
return ignoreEntitlementsForMigration;
}
/**
* This method should ONLY be used for system migrations, hence the long method name.
*
* This method will set a local flag (i.e. not Hibernate-related) that if set will
* result in skipping entitlement checking on various methods.
*
* @param ignoreIn Set to true to override entitlement sestings.
*/
public void setIgnoreEntitlementsForMigration(Boolean ignoreIn) {
this.ignoreEntitlementsForMigration = ignoreIn;
}
/**
* Get the NetworkInteface with the given name (i.e. eth0)
* @param ifName the interface name (i.e. eth0)
* @return the NetworkInterface, otherwise null
*/
public NetworkInterface getNetworkInterface(String ifName) {
for (NetworkInterface nic : getNetworkInterfaces()) {
if (nic.getName().equals(ifName)) {
return nic;
}
}
return null;
}
/**
* Returns the cobbler object associated to
* to this server.
* @param user the user object needed for connection,
* enter null if you want to use the
* automated connection as provided by
* taskomatic.
* @return the SystemRecord associated to this server
*/
public SystemRecord getCobblerObject(User user) {
if (StringUtils.isBlank(getCobblerId())) {
return null;
}
CobblerConnection con;
if (user == null) {
con = CobblerXMLRPCHelper.getAutomatedConnection();
}
else {
con = CobblerXMLRPCHelper.getConnection(user);
}
return SystemRecord.lookupById(con, getCobblerId());
}
/**
* @return Return application crashes.
*/
public CrashCount getCrashCount() {
return crashCount;
}
/**
* @param crashIn Set application crashes.
*/
public void setCrashCount(CrashCount crashIn) {
crashCount = crashIn;
}
/**
* @return primaryInterface Primary network interface
*/
public NetworkInterface getPrimaryInterface() {
return primaryInterface;
}
/**
* @param primaryInterfaceIn Primary network interface to be set
*/
public void setPrimaryInterface(NetworkInterface primaryInterfaceIn) {
primaryInterface = primaryInterfaceIn;
Iterator<NetworkInterface> i = networkInterfaces.iterator();
while (i.hasNext()) {
NetworkInterface n = i.next();
n.setPrimary(null);
}
SystemManager.storeServer(this);
primaryInterface.setPrimary("Y");
if (networks.size() == 1) {
Network n = networks.iterator().next();
n.setIpaddr(primaryInterface.getIpaddr());
n.setIp6addr(primaryInterface.getGlobalIpv6Addr());
}
}
/**
* @param interfaceName name of the interface
*/
public void setPrimaryInterfaceWithName(String interfaceName) {
setPrimaryInterface(findActiveIfaceWithName(interfaceName, false));
}
private NetworkInterface lookupForPrimaryInterface() {
for (NetworkInterface n : networkInterfaces) {
if (n.getPrimary() != null && n.getPrimary().equals("Y")) {
return n;
}
}
return null;
}
/**
* @return active Set of active interaces without lo
*/
public Set <NetworkInterface> getActiveNetworkInterfaces() {
Set <NetworkInterface> active = new HashSet();
for (NetworkInterface n : networkInterfaces) {
if (!n.isDisabled()) {
active.add(n);
}
}
return active;
}
/**
* @return Returns the crashes.
*/
public Set<Crash> getCrashes() {
return crashes;
}
/**
* @param c The crashes to set.
*/
public void setCrashes(Set<Crash> c) {
this.crashes = c;
}
/**
* @param interfaceName Name of the interface to be checked
* @return Returns true if yes, otherwise no
*/
public Boolean existsActiveInterfaceWithName(String interfaceName) {
return findActiveIfaceWithName(interfaceName, false) != null;
}
}