package io.cattle.platform.core.dao.impl; import static io.cattle.platform.core.model.tables.HostIpAddressMapTable.*; import static io.cattle.platform.core.model.tables.HostTable.*; import static io.cattle.platform.core.model.tables.IpAddressNicMapTable.*; import static io.cattle.platform.core.model.tables.IpAddressTable.*; import static io.cattle.platform.core.model.tables.NicTable.*; import io.cattle.platform.core.constants.CommonStatesConstants; import io.cattle.platform.core.constants.IpAddressConstants; import io.cattle.platform.core.dao.IpAddressDao; import io.cattle.platform.core.model.Host; import io.cattle.platform.core.model.HostIpAddressMap; import io.cattle.platform.core.model.Instance; import io.cattle.platform.core.model.IpAddress; import io.cattle.platform.core.model.IpAddressNicMap; import io.cattle.platform.core.model.Nic; import io.cattle.platform.core.model.tables.IpAddressTable; import io.cattle.platform.core.model.tables.NicTable; import io.cattle.platform.core.model.tables.records.IpAddressRecord; import io.cattle.platform.db.jooq.dao.impl.AbstractJooqDao; import io.cattle.platform.db.jooq.mapper.MultiRecordMapper; import io.cattle.platform.object.ObjectManager; import io.cattle.platform.object.process.ObjectProcessManager; import io.cattle.platform.object.process.StandardProcess; import io.cattle.platform.util.type.CollectionUtils; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; @Named public class IpAddressDaoImpl extends AbstractJooqDao implements IpAddressDao { @Inject ObjectManager objectManager; @Inject ObjectProcessManager processManager; @Override public IpAddress getPrimaryIpAddress(Nic nic) { List<? extends IpAddress> ipAddresses = create() .select(IP_ADDRESS.fields()) .from(IP_ADDRESS) .join(IP_ADDRESS_NIC_MAP) .on(IP_ADDRESS_NIC_MAP.IP_ADDRESS_ID.eq(IP_ADDRESS.ID) .and(IP_ADDRESS_NIC_MAP.NIC_ID.eq(nic.getId()))) .where(IP_ADDRESS_NIC_MAP.REMOVED.isNull()) .fetchInto(IpAddressRecord.class); if (ipAddresses.size() == 1) { return ipAddresses.get(0); } for (IpAddress ipAddress : ipAddresses) { if (IpAddressConstants.ROLE_PRIMARY.equals(ipAddress.getRole())) { return ipAddress; } } return null; } @Override public Map<Long, IpAddress> getNicIdToPrimaryIpAddress(long accountId) { final Map<Long, IpAddress> result = new HashMap<>(); MultiRecordMapper<List<Object>> mapper = new MultiRecordMapper<List<Object>>() { @Override protected List<Object> map(List<Object> input) { result.put(((Nic) input.get(0)).getId(), (IpAddress) input.get(1)); return input; } }; NicTable nic = mapper.add(NIC); IpAddressTable ipAddress = mapper.add(IP_ADDRESS); create() .select(mapper.fields()) .from(nic) .join(IP_ADDRESS_NIC_MAP) .on(IP_ADDRESS_NIC_MAP.NIC_ID.eq(nic.ID)) .join(ipAddress) .on(ipAddress.ID.eq(IP_ADDRESS_NIC_MAP.IP_ADDRESS_ID)) .where(ipAddress.NETWORK_ID.eq(nic.NETWORK_ID) .and(IP_ADDRESS_NIC_MAP.REMOVED.isNull()) .and(ipAddress.REMOVED.isNull()) .and(nic.REMOVED.isNull())) .and(nic.ACCOUNT_ID.eq(accountId)) .fetch().map(mapper); return result; } @Override public IpAddress mapNewIpAddress(Nic nic, Object key, Object... values) { if ( nic.getNetworkId() == null ) { throw new IllegalStateException("Can not map new IP to nic with no network assigned to nic"); } Map<Object,Object> inputProperties = key == null ? Collections.emptyMap() : CollectionUtils.asMap(key, values); Map<Object,Object> properties = CollectionUtils.asMap((Object)IP_ADDRESS.ACCOUNT_ID, nic.getAccountId()); properties.putAll(inputProperties); IpAddress ipAddress = objectManager.create(IpAddress.class, objectManager.convertToPropertiesFor(IpAddress.class, properties)); objectManager.create(IpAddressNicMap.class, IP_ADDRESS_NIC_MAP.IP_ADDRESS_ID, ipAddress.getId(), IP_ADDRESS_NIC_MAP.NIC_ID, nic.getId()); return ipAddress; } @Override public IpAddress assignAndActivateNewAddress(Host host, String ipAddress) { IpAddress ipAddressObj = objectManager.create(IpAddress.class, IP_ADDRESS.ADDRESS, ipAddress, IP_ADDRESS.ACCOUNT_ID, host.getAccountId()); HostIpAddressMap map = objectManager.create(HostIpAddressMap.class, HOST_IP_ADDRESS_MAP.IP_ADDRESS_ID, ipAddressObj.getId(), HOST_IP_ADDRESS_MAP.HOST_ID, host.getId()); processManager.scheduleStandardProcess(StandardProcess.CREATE, ipAddressObj, null); processManager.scheduleStandardProcess(StandardProcess.CREATE, map, null); return ipAddressObj; } @Override public IpAddress updateIpAddress(IpAddress ipAddress, String newIpAddress) { Map<String, Object> data = new HashMap<>(); if ( ipAddress.getAddress() != null ) { Map<String, Object> old = new HashMap<>(); old.put(IpAddressConstants.FIELD_ADDRESS, ipAddress.getAddress()); data.put("old", old); } objectManager.setFields(ipAddress, IP_ADDRESS.ADDRESS, newIpAddress); processManager.scheduleStandardProcess(StandardProcess.UPDATE, ipAddress, data); return ipAddress; } @Override public IpAddress getInstancePrimaryIp(Instance instance) { IpAddress ip = null; for (Nic nic : objectManager.children(instance, Nic.class)) { ip = getPrimaryIpAddress(nic); if (ip != null) { break; } } return ip; } @Override public List<? extends IpAddress> findBadHostIpAddress(int count) { return create().select(IP_ADDRESS.fields()) .from(IP_ADDRESS) .join(HOST_IP_ADDRESS_MAP) .on(HOST_IP_ADDRESS_MAP.IP_ADDRESS_ID.eq(IP_ADDRESS.ID)) .join(HOST) .on(HOST.ID.eq(HOST_IP_ADDRESS_MAP.HOST_ID)) .where(HOST.STATE.eq(CommonStatesConstants.PURGED) .and(IP_ADDRESS.REMOVED.isNull()) .and(IP_ADDRESS.STATE.notIn(CommonStatesConstants.REMOVING))) .limit(count) .fetchInto(IpAddressRecord.class); } }