blob: 320ac489ba9da309205f30c612a023fbfac607e6 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.network.contrail.management;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import javax.inject.Inject;
import net.juniper.contrail.api.ApiConnector;
import net.juniper.contrail.api.ApiObjectBase;
import net.juniper.contrail.api.ApiPropertyBase;
import net.juniper.contrail.api.ObjectReference;
import net.juniper.contrail.api.types.FloatingIp;
import net.juniper.contrail.api.types.FloatingIpPool;
import net.juniper.contrail.api.types.NetworkPolicy;
import net.juniper.contrail.api.types.InstanceIp;
import net.juniper.contrail.api.types.ServiceInstance;
import net.juniper.contrail.api.types.VirtualMachine;
import net.juniper.contrail.api.types.VirtualMachineInterface;
import net.juniper.contrail.api.types.VirtualNetwork;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.network.contrail.model.FloatingIpModel;
import org.apache.cloudstack.network.contrail.model.FloatingIpPoolModel;
import org.apache.cloudstack.network.contrail.model.NetworkPolicyModel;
import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel;
import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
import com.cloud.dc.dao.VlanDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InternalErrorException;
import com.cloud.network.IpAddress;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
import com.cloud.network.vpc.NetworkACLItemDao;
import com.cloud.network.vpc.NetworkACLItemVO;
import com.cloud.network.vpc.NetworkACLVO;
import com.cloud.network.vpc.dao.NetworkACLDao;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.projects.ProjectVO;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.vm.NicVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.VMInstanceDao;
@Component
public class ServerDBSyncImpl implements ServerDBSync {
@Inject
DomainDao _domainDao;
@Inject
ProjectDao _projectDao;
@Inject
NetworkDao _networksDao;
@Inject
VMInstanceDao _vmInstanceDao;
@Inject
NicDao _nicDao;
@Inject
VlanDao _vlanDao;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkServiceProviderDao _physProviderDao;
@Inject
ContrailManager _manager;
@Inject
VpcDao _vpcDao;
@Inject
NetworkACLItemDao _networkACLItemDao;
@Inject
NetworkACLDao _networkACLDao;
DBSyncGeneric _dbSync;
Class<?>[] _vncClasses;
// Read-Write (true) or Read-Only mode.
boolean _rwMode;
private final ReentrantLock _lockSyncMode = new ReentrantLock();
ServerDBSyncImpl() {
_vncClasses =
new Class[] {net.juniper.contrail.api.types.Domain.class, net.juniper.contrail.api.types.Project.class, NetworkPolicy.class, VirtualNetwork.class,
VirtualMachine.class, ServiceInstance.class, FloatingIp.class};
_dbSync = new DBSyncGeneric(this);
}
private static final Logger s_logger = Logger.getLogger(ServerDBSync.class);
/*
* API for syncing all classes of vnc objects with cloudstack
*
* Sync cloudstack and vnc objects.
* Order has to be maintained
*/
@Override
public short syncAll(short syncMode) {
short syncState = SYNC_STATE_IN_SYNC;
/* vnc classes need to be synchronized with cloudstack */
s_logger.debug("syncing cloudstack db with vnc");
try {
for (Class<?> cls : _vncClasses) {
/* lock the sync mode*/
_lockSyncMode.lock();
_rwMode = syncMode == DBSyncGeneric.SYNC_MODE_UPDATE;
_dbSync.setSyncMode(syncMode);
if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
s_logger.debug("sync check start: " + DBSyncGeneric.getClassName(cls));
} else {
s_logger.debug("sync start: " + DBSyncGeneric.getClassName(cls));
}
if (_dbSync.sync(cls) == false) {
if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
s_logger.info("out of sync detected: " + DBSyncGeneric.getClassName(cls));
} else {
s_logger.info("out of sync detected and re-synced: " + DBSyncGeneric.getClassName(cls));
}
syncState = SYNC_STATE_OUT_OF_SYNC;
}
if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
s_logger.debug("sync check finish: " + DBSyncGeneric.getClassName(cls));
} else {
s_logger.debug("sync finish: " + DBSyncGeneric.getClassName(cls));
}
/* unlock the sync mode */
_lockSyncMode.unlock();
}
} catch (Exception ex) {
s_logger.warn("DB Synchronization", ex);
syncState = SYNC_STATE_UNKNOWN;
if (_lockSyncMode.isLocked()) {
_lockSyncMode.unlock();
}
}
return syncState;
}
@Override
public void syncClass(Class<?> cls) {
s_logger.debug("syncClass: " + cls.getName());
try {
s_logger.debug("sync start: " + DBSyncGeneric.getClassName(cls));
_lockSyncMode.lock();
_dbSync.setSyncMode(DBSyncGeneric.SYNC_MODE_UPDATE);
_dbSync.sync(cls);
_lockSyncMode.unlock();
s_logger.debug("sync finish: " + DBSyncGeneric.getClassName(cls));
} catch (Exception ex) {
s_logger.warn("Sync error: " + cls.getName(), ex);
if (_lockSyncMode.isLocked()) {
_lockSyncMode.unlock();
}
}
}
public <T extends ApiPropertyBase> void deleteChildren(List<ObjectReference<T>> childs, Class<?> childCls, StringBuffer syncLogMesg) throws Exception {
final ApiConnector api = _manager.getApiConnector();
if (childs == null) {
syncLogMesg.append("no children of type: " + childCls.getName() + "\n");
return;
}
syncLogMesg.append("delete children of type : " + DBSyncGeneric.getClassName(childCls) + "\n");
String deleteChildMethod = "delete" + DBSyncGeneric.getClassName(childCls);
Method method = null;
Method methods[] = this.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equalsIgnoreCase(deleteChildMethod)) {
method = methods[i];
break;
}
}
int count = 0;
for (ObjectReference<T> childRef : childs) {
@SuppressWarnings("unchecked")
ApiObjectBase child = api.findById((Class<? extends ApiObjectBase>)childCls, childRef.getUuid());
if (method != null) {
method.invoke(this, child, syncLogMesg);
} else {
deleteDefault(child, childCls, syncLogMesg);
}
count++;
}
syncLogMesg.append("deleted children count : " + count + "\n");
}
public void deleteDefault(ApiObjectBase vnc, Class<?> cls, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
api.delete(vnc);
syncLogMesg.append(cls.getCanonicalName() + "# VNC: " + vnc.getName() + " deleted\n");
}
/*
* Domain Synchronization methods
*/
public boolean syncDomain() throws Exception {
final ApiConnector api = _manager.getApiConnector();
try {
List<?> dbList = _domainDao.listAll();
@SuppressWarnings("unchecked")
List<?> vncList = api.list(net.juniper.contrail.api.types.Domain.class, null);
return _dbSync.syncGeneric(net.juniper.contrail.api.types.Domain.class, dbList, vncList);
} catch (Exception ex) {
s_logger.warn("syncDomain", ex);
throw ex;
}
}
@Override
public void createDomain(DomainVO db, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
net.juniper.contrail.api.types.Domain vnc = new net.juniper.contrail.api.types.Domain();
vnc.setName(db.getName());
vnc.setUuid(db.getUuid());
if (!api.create(vnc)) {
s_logger.error("Unable to create domain " + vnc.getName());
syncLogMesg.append("Error: Virtual domain# VNC : Unable to create domain: " + vnc.getName() + "\n");
return;
}
syncLogMesg.append("Domain# VNC: " + vnc.getName() + " created \n");
}
public void deleteDomain(net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
api.read(vnc);
syncLogMesg.append("Domain# DB: none; VNC: " + vnc.getName() + "(" + vnc.getUuid() + "); action: delete\n");
/* delete all projects under this domain */
try {
deleteChildren(vnc.getProjects(), net.juniper.contrail.api.types.Project.class, syncLogMesg);
} catch (Exception ex) {
s_logger.warn("deleteDomain", ex);
}
api.delete(vnc);
syncLogMesg.append("Domain# VNC: " + vnc.getName() + " deleted\n");
}
public Integer compareDomain(DomainVO db, net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) {
if (_manager.isSystemRootDomain(db) && _manager.isSystemRootDomain(vnc)) {
return _manager.getDomainCanonicalName(db).compareTo(vnc.getName());
} else if (_manager.isSystemRootDomain(db)) {
return -1;
} else if (_manager.isSystemRootDomain(vnc)) {
return 1;
}
return db.getUuid().compareTo(vnc.getUuid());
}
public Boolean filterDomain(net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) {
if (_manager.isSystemRootDomain(vnc)) {
return true;
}
return false;
}
public Boolean equalDomain(DomainVO db, net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) {
syncLogMesg.append("Domain# DB: " + db.getName() + "; VNC: " + vnc.getName() + "; action: equal, no action\n");
return true;
}
public Comparator<?> dbComparatorDomain() {
Comparator<?> comparator = new Comparator<DomainVO>() {
@Override
public int compare(DomainVO u1, DomainVO u2) {
if (_manager.isSystemRootDomain(u1)) {
return -1;
}
if (_manager.isSystemRootDomain(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorDomain() {
Comparator<?> comparator = new Comparator<net.juniper.contrail.api.types.Domain>() {
@Override
public int compare(net.juniper.contrail.api.types.Domain u1, net.juniper.contrail.api.types.Domain u2) {
if (_manager.isSystemRootDomain(u1)) {
return -1;
}
if (_manager.isSystemRootDomain(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
/*
* Project Synchronization methods
*/
@SuppressWarnings("unchecked")
public boolean syncProject() throws Exception {
final ApiConnector api = _manager.getApiConnector();
try {
List<?> dbList = _projectDao.listAll();
List<?> vncList = api.list(net.juniper.contrail.api.types.Project.class, null);
return _dbSync.syncGeneric(net.juniper.contrail.api.types.Project.class, dbList, vncList);
} catch (Exception ex) {
s_logger.warn("syncProject", ex);
throw ex;
}
}
@Override
public void createProject(ProjectVO db, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
net.juniper.contrail.api.types.Project vnc = new net.juniper.contrail.api.types.Project();
vnc.setName(db.getName());
vnc.setUuid(db.getUuid());
if (!api.create(vnc)) {
s_logger.error("Unable to create project: " + vnc.getName());
syncLogMesg.append("Error: Virtual project# VNC : Unable to create project: " + vnc.getName() + "\n");
return;
}
syncLogMesg.append("Project# VNC: " + vnc.getName() + " created \n");
}
public void deleteProject(net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
api.read(vnc);
syncLogMesg.append("Project# DB: none; VNC: " + vnc.getName() + "(" + vnc.getUuid() + "); action: delete\n");
try {
deleteChildren(vnc.getVirtualNetworks(), VirtualNetwork.class, syncLogMesg);
deleteChildren(vnc.getSecurityGroups(), net.juniper.contrail.api.types.SecurityGroup.class, syncLogMesg);
deleteChildren(vnc.getNetworkIpams(), net.juniper.contrail.api.types.NetworkIpam.class, syncLogMesg);
deleteChildren(vnc.getNetworkPolicys(), net.juniper.contrail.api.types.NetworkPolicy.class, syncLogMesg);
} catch (Exception ex) {
s_logger.warn("deleteProject", ex);
}
api.delete(vnc);
syncLogMesg.append("Project# VNC: " + vnc.getName() + " deleted\n");
}
public Integer compareProject(ProjectVO db, net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultProject(db) && _manager.isSystemDefaultProject(vnc)) {
return _manager.getProjectCanonicalName(db).compareTo(vnc.getName());
} else if (_manager.isSystemDefaultProject(db)) {
return -1;
} else if (_manager.isSystemDefaultProject(vnc)) {
return 1;
}
return db.getUuid().compareTo(vnc.getUuid());
}
public Boolean filterProject(net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultProject(vnc)) {
syncLogMesg.append("VNC: " + vnc.getName() + " filtered; action: don't delete\n");
return true;
}
return false;
}
public Boolean equalProject(ProjectVO db, net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) {
syncLogMesg.append("Project# DB: " + db.getName() + "; VNC: " + vnc.getName() + "; action: equal, no action\n");
return true;
}
public Comparator<?> dbComparatorProject() {
Comparator<?> comparator = new Comparator<ProjectVO>() {
@Override
public int compare(ProjectVO u1, ProjectVO u2) {
if (_manager.isSystemDefaultProject(u1)) {
return -1;
}
if (_manager.isSystemDefaultProject(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorProject() {
Comparator<?> comparator = new Comparator<net.juniper.contrail.api.types.Project>() {
@Override
public int compare(net.juniper.contrail.api.types.Project u1, net.juniper.contrail.api.types.Project u2) {
if (_manager.isSystemDefaultProject(u1)) {
return -1;
}
if (_manager.isSystemDefaultProject(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
/*
* Security Groups
*/
public void deleteSecurityGroup(net.juniper.contrail.api.types.SecurityGroup vnc, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
api.delete(vnc);
syncLogMesg.append("SecurityGroup# VNC: " + vnc.getName() + " deleted\n");
}
/*
* Virtual Network Synchronization methods
*/
@SuppressWarnings({"unchecked"})
public boolean syncVirtualNetwork() throws Exception {
final ApiConnector api = _manager.getApiConnector();
try {
List<TrafficType> types = new ArrayList<TrafficType>();
types.add(TrafficType.Public);
types.add(TrafficType.Guest);
List<NetworkVO> dbNets = _manager.findManagedNetworks(types);
List<VirtualNetwork> vList = (List<VirtualNetwork>)api.list(VirtualNetwork.class, null);
List<VirtualNetwork> vncList = new ArrayList<VirtualNetwork>();
for (VirtualNetwork vn : vList) {
if (!_manager.isSystemDefaultNetwork(vn)) {
vncList.add(vn);
}
}
s_logger.debug("sync VN - DB size: " + dbNets.size() + " VNC Size: " + vncList.size());
return _dbSync.syncGeneric(VirtualNetwork.class, dbNets, vncList);
} catch (Exception ex) {
s_logger.warn("sync virtual-networks", ex);
throw ex;
}
}
public Comparator<NetworkVO> dbComparatorVirtualNetwork() {
Comparator<NetworkVO> comparator = new Comparator<NetworkVO>() {
@Override
public int compare(NetworkVO u1, NetworkVO u2) {
if (_manager.isSystemDefaultNetwork(u1) && _manager.isSystemDefaultNetwork(u2)) {
return _manager.getCanonicalName(u1).compareTo(_manager.getCanonicalName(u2));
} else if (_manager.isSystemDefaultNetwork(u1)) {
return -1;
} else if (_manager.isSystemDefaultNetwork(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorVirtualNetwork() {
Comparator<?> comparator = new Comparator<VirtualNetwork>() {
@Override
public int compare(VirtualNetwork u1, VirtualNetwork u2) {
if (_manager.isSystemDefaultNetwork(u1) && _manager.isSystemDefaultNetwork(u2)) {
return u1.getName().compareTo(u2.getName());
} else if (_manager.isSystemDefaultNetwork(u1)) {
return -1;
} else if (_manager.isSystemDefaultNetwork(u2)) {
return 1;
}
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public void createVirtualNetwork(NetworkVO dbNet, StringBuffer syncLogMesg) throws IOException {
syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbNet) + "(" + dbNet.getUuid() + "); VNC: none; action: create\n");
if (_manager.getDatabase().lookupVirtualNetwork(dbNet.getUuid(), _manager.getCanonicalName(dbNet), dbNet.getTrafficType()) != null) {
s_logger.warn("VN model object is already present in DB: " + dbNet.getUuid() + ", name: " + dbNet.getName());
}
VirtualNetworkModel vnModel = new VirtualNetworkModel(dbNet, dbNet.getUuid(), _manager.getCanonicalName(dbNet), dbNet.getTrafficType());
if (dbNet.getTrafficType() == TrafficType.Guest && dbNet.getNetworkACLId() != null) {
NetworkACLVO acl = _networkACLDao.findById(dbNet.getNetworkACLId());
NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid());
if (policyModel == null) {
s_logger.error("Network(" + dbNet.getName() + ") has ACL but policy model not created: " +
acl.getUuid() + ", name: " + acl.getName());
} else {
vnModel.addToNetworkPolicy(policyModel);
}
}
vnModel.build(_manager.getModelController(), dbNet);
if (_rwMode) {
try {
if (!vnModel.verify(_manager.getModelController())) {
vnModel.update(_manager.getModelController());
}
} catch (InternalErrorException ex) {
s_logger.warn("create virtual-network", ex);
syncLogMesg.append("Error: VN# VNC : Unable to create network " + dbNet.getName() + "\n");
return;
}
s_logger.debug("add model " + vnModel.getName());
_manager.getDatabase().getVirtualNetworks().add(vnModel);
syncLogMesg.append("VN# VNC: " + dbNet.getUuid() + ", " + vnModel.getName() + " created\n");
} else {
syncLogMesg.append("VN# VNC: " + vnModel.getName() + " created \n");
}
}
public void deleteVirtualNetwork(VirtualNetwork vnet, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
if (_manager.isSystemDefaultNetwork(vnet)) {
syncLogMesg.append("VN# System default virtual Network# VNC: " + vnet.getName() + " can not be deleted\n");
return;
}
api.read(vnet);
deleteInstanceIps(vnet.getInstanceIpBackRefs(), syncLogMesg);
List<ObjectReference<ApiPropertyBase>> fipPools = vnet.getFloatingIpPools();
if (fipPools != null && !fipPools.isEmpty()) {
FloatingIpPool floatingIpPool = (FloatingIpPool)api.findById(FloatingIpPool.class, fipPools.get(0).getUuid());
if (floatingIpPool != null) {
deleteFloatingIps(floatingIpPool.getFloatingIps(), syncLogMesg);
}
}
deleteVirtualMachineInterfaces(vnet.getVirtualMachineInterfaceBackRefs(), syncLogMesg);
syncLogMesg.append("VN# DB: none; VNC: " + vnet.getName() + "(" + vnet.getUuid() + "); action: delete\n");
api.delete(vnet);
syncLogMesg.append("VN# VNC: " + vnet.getName() + " deleted\n");
}
public Integer compareVirtualNetwork(NetworkVO dbn, VirtualNetwork vnet, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultNetwork(dbn) && _manager.isSystemDefaultNetwork(vnet)) {
return _manager.getCanonicalName(dbn).compareTo(vnet.getName());
} else if (_manager.isSystemDefaultNetwork(dbn)) {
return -1;
} else if (_manager.isSystemDefaultNetwork(vnet)) {
return 1;
}
return dbn.getUuid().compareTo(vnet.getUuid());
}
public Boolean filterVirtualNetwork(VirtualNetwork vnet, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultNetwork(vnet)) {
syncLogMesg.append("VN# VNC: " + vnet.getName() + " filtered; action: don't delete\n");
return true;
}
return false;
}
public Boolean equalVirtualNetwork(NetworkVO dbn, VirtualNetwork vnet, StringBuffer syncLogMesg) {
syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbn) + "; VNC: " + vnet.getName() + "; action: equal\n");
VirtualNetworkModel current = _manager.getDatabase().lookupVirtualNetwork(vnet.getUuid(), _manager.getCanonicalName(dbn), dbn.getTrafficType());
VirtualNetworkModel vnModel = new VirtualNetworkModel(dbn, vnet.getUuid(), _manager.getCanonicalName(dbn), dbn.getTrafficType());
if (dbn.getTrafficType() == TrafficType.Guest && dbn.getNetworkACLId() != null) {
NetworkACLVO acl = _networkACLDao.findById(dbn.getNetworkACLId());
NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid());
if (policyModel == null) {
s_logger.error("Network(" + dbn.getName() + ") has ACL but policy model not created: " +
acl.getUuid() + ", name: " + acl.getName());
} else {
vnModel.addToNetworkPolicy(policyModel);
}
}
vnModel.build(_manager.getModelController(), dbn);
if (_rwMode) {
if (current != null) {
FloatingIpPoolModel fipPoolModel = current.getFipPoolModel();
if (fipPoolModel != null) {
vnModel.setFipPoolModel(fipPoolModel);
fipPoolModel.addToVirtualNetwork(vnModel);
}
_manager.getDatabase().getVirtualNetworks().remove(current);
}
s_logger.debug("add model " + vnModel.getName());
_manager.getDatabase().getVirtualNetworks().add(vnModel);
try {
if (!vnModel.verify(_manager.getModelController())) {
vnModel.update(_manager.getModelController());
}
} catch (Exception ex) {
s_logger.warn("update virtual-network", ex);
}
if (current != null) {
NetworkPolicyModel oldPolicyModel = current.getNetworkPolicyModel();
if (oldPolicyModel != vnModel.getNetworkPolicyModel()) {
/*
* if no other VNs are associated with the old policy,
* we could delete it from the Contrail VNC
*/
if (oldPolicyModel != null && !oldPolicyModel.hasDescendents()) {
try {
oldPolicyModel.delete(_manager.getModelController());
_manager.getDatabase().getNetworkPolicys().remove(oldPolicyModel);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} else {
//compare
if (current != null && current.compare(_manager.getModelController(), vnModel) == false) {
syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbn) + "; VNC: " + vnet.getName() + "; attributes differ\n");
return false;
}
}
return true;
}
/*
* Virtual Machine Synchronization methods
*/
public boolean syncVirtualMachine() {
final ApiConnector api = _manager.getApiConnector();
try {
List<VMInstanceVO> vmDbList = _vmInstanceDao.listAll();
@SuppressWarnings("unchecked")
List<VirtualMachine> vncVmList = (List<VirtualMachine>)api.list(VirtualMachine.class, null);
s_logger.debug("sync VM: CS size: " + vmDbList.size() + " VNC size: " + vncVmList.size());
return _dbSync.syncGeneric(VirtualMachine.class, vmDbList, vncVmList);
} catch (Exception ex) {
s_logger.warn("sync virtual-machines", ex);
}
return false;
}
public Comparator<?> dbComparatorVirtualMachine() {
Comparator<?> comparator = new Comparator<VMInstanceVO>() {
@Override
public int compare(VMInstanceVO u1, VMInstanceVO u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorVirtualMachine() {
Comparator<?> comparator = new Comparator<VirtualMachine>() {
@Override
public int compare(VirtualMachine u1, VirtualMachine u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public void createVirtualMachine(VMInstanceVO dbVm, StringBuffer syncLogMesg) throws IOException {
syncLogMesg.append("VM# DB: " + dbVm.getInstanceName() + "/" + dbVm.getUuid() + "; VNC: none; action: create\n");
VirtualMachineModel vmModel = new VirtualMachineModel(dbVm, dbVm.getUuid());
vmModel.build(_manager.getModelController(), dbVm);
buildNicResources(vmModel, dbVm, syncLogMesg);
if (_rwMode) {
try {
vmModel.update(_manager.getModelController());
} catch (InternalErrorException ex) {
s_logger.warn("create virtual-machine", ex);
return;
}
_manager.getDatabase().getVirtualMachines().add(vmModel);
syncLogMesg.append("VM# VNC: " + dbVm.getUuid() + " created\n");
}
}
private void deleteVirtualMachineInterfaces(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
if (list == null) {
return;
}
final ApiConnector api = _manager.getApiConnector();
for (ObjectReference<ApiPropertyBase> vmiRef : list) {
VirtualMachineInterface vmi = (VirtualMachineInterface)api.findById(VirtualMachineInterface.class, vmiRef.getUuid());
deleteInstanceIps(vmi.getInstanceIpBackRefs(), syncLogMesg);
deleteFloatingIps(vmi.getFloatingIpBackRefs(), syncLogMesg);
api.delete(VirtualMachineInterface.class, vmiRef.getUuid());
syncLogMesg.append("VNC vmi: " + vmi.getUuid() + " deleted\n");
}
}
private void deleteInstanceIps(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
if (list == null) {
return;
}
final ApiConnector api = _manager.getApiConnector();
for (ObjectReference<ApiPropertyBase> instIp : list) {
api.delete(InstanceIp.class, instIp.getUuid());
syncLogMesg.append("VNC instance ip: " + instIp.getUuid() + " deleted\n");
}
}
private void deleteFloatingIps(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
if (list == null) {
return;
}
final ApiConnector api = _manager.getApiConnector();
for (ObjectReference<?> floatingIp : list) {
api.delete(FloatingIp.class, floatingIp.getUuid());
syncLogMesg.append("VNC instance ip: " + floatingIp.getUuid() + " deleted\n");
}
}
public void deleteVirtualMachine(VirtualMachine vncVm, StringBuffer syncLogMesg) {
final ApiConnector api = _manager.getApiConnector();
syncLogMesg.append("VM# DB:none; VNC: " + vncVm.getName() + "/" + vncVm.getUuid() + "; action: delete\n");
if (!_rwMode) {
return;
}
try {
if (!api.read(vncVm)) {
return;
}
deleteVirtualMachineInterfaces(vncVm.getVirtualMachineInterfaces(), syncLogMesg);
api.delete(VirtualMachine.class, vncVm.getUuid());
} catch (IOException ex) {
s_logger.warn("delete virtual-machine", ex);
return;
}
syncLogMesg.append("VM# VNC: " + vncVm.getName() + " deleted\n");
}
public Integer compareVirtualMachine(VMInstanceVO dbVm, VirtualMachine vncVm, StringBuffer syncLogMesg) {
String dbVmId = dbVm.getUuid();
String vncVmId = vncVm.getUuid();
return dbVmId.compareTo(vncVmId);
}
public boolean filterVirtualMachine(VirtualMachine vncVm, StringBuffer syncLogMesg) {
return false;
}
private void buildNicResources(VirtualMachineModel vmModel, VMInstanceVO dbVm, StringBuffer syncLogMsg) throws IOException {
List<NicVO> nics = _nicDao.listByVmId(dbVm.getId());
for (NicVO nic : nics) {
VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
if (vmiModel == null) {
vmiModel = new VMInterfaceModel(nic.getUuid());
NetworkVO network = _networksDao.findById(nic.getNetworkId());
VirtualNetworkModel vnModel =
_manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
if (vnModel == null) {
s_logger.warn("Unable to locate virtual-network for network id " + network.getId());
continue;
}
vmiModel.addToVirtualMachine(vmModel);
vmiModel.addToVirtualNetwork(vnModel);
}
vmiModel.build(_manager.getModelController(), dbVm, nic);
}
}
public Boolean equalVirtualMachine(VMInstanceVO dbVm, VirtualMachine vncVm, StringBuffer syncLogMsg) {
syncLogMsg.append("VM# DB: " + dbVm.getInstanceName() + "/" + dbVm.getUuid() + "; VNC: " + vncVm.getUuid() + "; action: equal; DB VM State: " + dbVm.getState() +
"\n");
VirtualMachineModel vmModel = new VirtualMachineModel(dbVm, dbVm.getUuid());
vmModel.build(_manager.getModelController(), dbVm);
if (vmModel.isActive()) {
try {
buildNicResources(vmModel, dbVm, syncLogMsg);
} catch (IOException ex) {
s_logger.warn("build nic information for " + dbVm.getInstanceName(), ex);
}
}
VirtualMachineModel current = _manager.getDatabase().lookupVirtualMachine(vncVm.getUuid());
if (_rwMode) {
if (current != null) {
_manager.getDatabase().getVirtualMachines().remove(current);
}
_manager.getDatabase().getVirtualMachines().add(vmModel);
try {
vmModel.update(_manager.getModelController());
} catch (Exception ex) {
s_logger.warn("update virtual-machine", ex);
}
} else {
//compare
if (current != null && current.compare(_manager.getModelController(), vmModel) == false) {
syncLogMsg.append("VM # DB: " + dbVm.getInstanceName() + "; VNC: " + vncVm.getName() + "; attributes differ\n");
return false;
}
}
return true;
}
public boolean syncFloatingIp() throws Exception {
List<IPAddressVO> ipList = _manager.findManagedPublicIps();
List<FloatingIp> vncList = _manager.getFloatingIps();
if (ipList == null) {
ipList = new ArrayList<IPAddressVO>();
}
if (vncList == null) {
vncList = new ArrayList<FloatingIp>();
}
boolean status = false;
try {
status = _dbSync.syncGeneric(FloatingIp.class, ipList, vncList);
} catch (Exception ex) {
s_logger.warn("sync floating-ips", ex);
throw ex;
}
return status;
}
public Comparator<?> dbComparatorFloatingIp() {
Comparator<?> comparator = new Comparator<IpAddress>() {
@Override
public int compare(IpAddress u1, IpAddress u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorFloatingIp() {
Comparator<?> comparator = new Comparator<FloatingIp>() {
@Override
public int compare(FloatingIp u1, FloatingIp u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Integer compareFloatingIp(IpAddress db, FloatingIp vnc, StringBuffer syncLogMesg) {
String dbId = db.getUuid();
String vncId = vnc.getUuid();
return dbId.compareTo(vncId);
}
public void createFloatingIp(IPAddressVO dbIp, StringBuffer syncLogMesg) throws Exception {
if (dbIp.getState() == IpAddress.State.Releasing) {
/* Don't need to push releasing ip */
syncLogMesg.append("fip# DB: " + dbIp.getUuid() + ", state releasing, don't create in vnc\n");
return;
}
syncLogMesg.append("fip# DB: " + dbIp.getAddress().addr() + "; VNC: none; action: create\n");
if (!_manager.createFloatingIp(PublicIp.createFromAddrAndVlan(dbIp, _vlanDao.findById(dbIp.getVlanId())))) {
syncLogMesg.append("fip# VNC: " + dbIp.getAddress().addr() + " unable to create\n");
return;
}
syncLogMesg.append("fip# VNC: " + dbIp.getUuid() + " created\n");
}
public void deleteFloatingIp(FloatingIp vnc, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
syncLogMesg.append("fip# DB: none; VNC: " + vnc.getAddress() + "(" + vnc.getUuid() + "); action: delete\n");
api.delete(vnc);
syncLogMesg.append("fip# VNC: " + vnc.getUuid() + " deleted\n");
}
public Boolean equalFloatingIp(IPAddressVO db, FloatingIp vnc, StringBuffer syncLogMsg) throws IOException {
syncLogMsg.append("fip# DB: " + db.getAddress().addr() + "; VNC: " + vnc.getAddress() + "; action: equal" + "\n");
VirtualNetworkModel vnModel = _manager.lookupPublicNetworkModel();
assert vnModel != null : "public network vn model is null";
FloatingIpPoolModel fipPoolModel = vnModel.getFipPoolModel();
if (fipPoolModel == null) {
fipPoolModel = new FloatingIpPoolModel();
fipPoolModel.addToVirtualNetwork(vnModel);
fipPoolModel.build(_manager.getModelController());
try {
fipPoolModel.update(_manager.getModelController());
vnModel.setFipPoolModel(fipPoolModel);
} catch (Exception ex) {
s_logger.warn("floating-ip-pool create: ", ex);
return false;
}
}
FloatingIpModel current = fipPoolModel.getFloatingIpModel(db.getUuid());
if (current == null) {
s_logger.debug("add model " + db.getAddress().addr());
FloatingIpModel fipModel = new FloatingIpModel(db.getUuid());
fipModel.addToFloatingIpPool(fipPoolModel);
fipModel.build(_manager.getModelController(), PublicIp.createFromAddrAndVlan(db, _vlanDao.findById(db.getVlanId())));
try {
fipModel.update(_manager.getModelController());
} catch (Exception ex) {
s_logger.warn("floating-ip create: ", ex);
return false;
}
}
return true;
}
/*
* Network Policy Synchronization methods
*/
@SuppressWarnings({ "unchecked" })
public boolean syncNetworkPolicy() throws Exception {
final ApiConnector api = _manager.getApiConnector();
try {
List<NetworkACLVO> dbAcls = _manager.findManagedACLs();
if (dbAcls == null) {
dbAcls = new ArrayList<NetworkACLVO>();
}
List<NetworkPolicy> pList = (List<NetworkPolicy>) api.list(NetworkPolicy.class, null);
List<NetworkPolicy> vncList = new ArrayList<NetworkPolicy>();
for (NetworkPolicy policy:pList) {
if (!_manager.isSystemDefaultNetworkPolicy(policy)) {
vncList.add(policy);
}
}
s_logger.debug("sync Network Policy - DB size: " + dbAcls.size() + " VNC Size: " + vncList.size());
return _dbSync.syncGeneric(NetworkPolicy.class, dbAcls, vncList);
} catch (Exception ex) {
s_logger.warn("sync network-policys", ex);
throw ex;
}
}
public Comparator<NetworkACLVO> dbComparatorNetworkPolicy() {
Comparator<NetworkACLVO> comparator = new Comparator<NetworkACLVO>() {
public int compare(NetworkACLVO u1, NetworkACLVO u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public Comparator<?> vncComparatorNetworkPolicy() {
Comparator<?> comparator = new Comparator<NetworkPolicy>() {
public int compare(NetworkPolicy u1, NetworkPolicy u2) {
return u1.getUuid().compareTo(u2.getUuid());
}
};
return comparator;
}
public void createNetworkPolicy(NetworkACLVO db, StringBuffer syncLogMesg) throws IOException {
syncLogMesg.append("Policy# DB: " + db.getName() +
"(" + db.getUuid() + "); VNC: none; action: create\n");
if (_manager.getDatabase().lookupNetworkPolicy(db.getUuid()) != null) {
s_logger.warn("Policy model object is already present in DB: " +
db.getUuid() + ", name: " + db.getName());
}
NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName());
net.juniper.contrail.api.types.Project project = null;
try {
VpcVO vpc = _vpcDao.findById(db.getVpcId());
if (vpc != null) {
project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId());
} else {
project = _manager.getDefaultVncProject();
}
} catch (IOException ex) {
s_logger.warn("read project", ex);
throw ex;
}
policyModel.setProject(project);
List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(db.getId());
try {
policyModel.build(_manager.getModelController(), rules);
} catch (Exception e) {
e.printStackTrace();
}
if (_rwMode) {
try {
if (!policyModel.verify(_manager.getModelController())) {
policyModel.update(_manager.getModelController());
}
} catch (Exception ex) {
s_logger.warn("create network-policy", ex);
syncLogMesg.append("Error: Policy# VNC : Unable to create network policy " +
db.getName() + "\n");
return;
}
s_logger.debug("add model " + policyModel.getName());
_manager.getDatabase().getNetworkPolicys().add(policyModel);
syncLogMesg.append("Policy# VNC: " + db.getUuid() + ", " + policyModel.getName() + " created\n");
} else {
syncLogMesg.append("Policy# VNC: " + policyModel.getName() + " created \n");
}
}
public void deleteNetworkPolicy(NetworkPolicy policy, StringBuffer syncLogMesg) throws IOException {
final ApiConnector api = _manager.getApiConnector();
if (_manager.isSystemDefaultNetworkPolicy(policy)) {
syncLogMesg.append("Policy# System default Network Policy# VNC: " + policy.getName() + " can not be deleted\n");
return;
}
syncLogMesg.append("Policy# DB: none; VNC: " + policy.getName() + "(" + policy.getUuid() + "); action: delete\n");
api.delete(policy);
syncLogMesg.append("Policy# VNC: " + policy.getName() + " deleted\n");
}
public Integer compareNetworkPolicy(NetworkACLVO dbn, NetworkPolicy policy, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultNetworkPolicy(policy)) {
return 1;
}
return dbn.getUuid().compareTo(policy.getUuid());
}
public Boolean filterNetworkPolicy(NetworkPolicy policy, StringBuffer syncLogMesg) {
if (_manager.isSystemDefaultNetworkPolicy(policy)) {
syncLogMesg.append("Policy# VNC: " + policy.getName() + " filtered; action: don't delete\n");
return true;
}
return false;
}
public Boolean equalNetworkPolicy(NetworkACLVO db, NetworkPolicy policy, StringBuffer syncLogMesg) {
syncLogMesg.append("Policy# DB: " + db.getName() +
"; VNC: " + policy.getName() + "; action: equal\n");
NetworkPolicyModel current = _manager.getDatabase().lookupNetworkPolicy(policy.getUuid());
NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName());
net.juniper.contrail.api.types.Project project = null;
try {
VpcVO vpc = _vpcDao.findById(db.getVpcId());
if (vpc != null) {
project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId());
} else {
project = _manager.getDefaultVncProject();
}
} catch (IOException ex) {
s_logger.warn("read project", ex);
}
policyModel.setProject(project);
List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(db.getId());
try {
policyModel.build(_manager.getModelController(), rules);
} catch (Exception e) {
e.printStackTrace();
}
if (_rwMode) {
if (current != null) {
_manager.getDatabase().getNetworkPolicys().remove(current);
}
s_logger.debug("add policy model " + policyModel.getName());
_manager.getDatabase().getNetworkPolicys().add(policyModel);
try {
if (!policyModel.verify(_manager.getModelController())) {
policyModel.update(_manager.getModelController());
}
} catch (Exception ex) {
s_logger.warn("update network-policy", ex);
}
} else {
//compare
if (current != null && current.compare(_manager.getModelController(), policyModel) == false) {
syncLogMesg.append("Policy# DB: " + db.getName() +
"; VNC: " + policy.getName() + "; attributes differ\n");
return false;
}
}
return true;
}
public Integer compareServiceInstance(ServiceInstanceModel siModel, ServiceInstance siObj, StringBuffer logMsg) {
String fqn = StringUtils.join(siObj.getQualifiedName(), ':');
return siModel.getQualifiedName().compareTo(fqn);
}
/**
* createServiceInstance
*
* This method should never be invoked since the model objects have been installed already when sync is called.
* @param siModel
* @param logMsg
*/
public void createServiceInstance(ServiceInstanceModel siModel, StringBuffer logMsg) {
assert false;
}
public void deleteServiceInstance(ServiceInstance siObj, StringBuffer logMsg) {
final ApiConnector api = _manager.getApiConnector();
s_logger.debug("delete " + siObj.getQualifiedName());
if (!_rwMode) {
return;
}
try {
api.delete(siObj);
} catch (IOException ex) {
s_logger.warn("service-instance delete", ex);
}
}
/**
* equalServiceInstance
*
* @param siModel
* @param siObj
* @param logMsg
*/
public void equalServiceInstance(ServiceInstanceModel siModel, ServiceInstance siObj, StringBuffer logMsg) {
s_logger.debug("equal " + siModel.getQualifiedName());
}
static class ServiceInstanceComparator implements Comparator<ServiceInstance>, Serializable {
@Override
public int compare(ServiceInstance obj1, ServiceInstance obj2) {
String name1 = StringUtils.join(obj1.getQualifiedName(), ':');
String name2 = StringUtils.join(obj2.getQualifiedName(), ':');
return name1.compareTo(name2);
}
}
/**
* The service-instance model list is build as a result of synchronizing virtual-machines.
* @return
*/
public boolean syncServiceInstance() {
final ApiConnector api = _manager.getApiConnector();
boolean inSync;
try {
@SuppressWarnings("unchecked")
List<ServiceInstance> siList = (List<ServiceInstance>)api.list(ServiceInstance.class, null);
java.util.Collections.sort(siList, new ServiceInstanceComparator());
DBSyncGeneric.SyncStats stats = new DBSyncGeneric.SyncStats();
_dbSync.syncCollections(ServiceInstance.class, _manager.getDatabase().getServiceInstances(), siList, _rwMode, stats);
inSync = stats.create == 0 && stats.delete == 0;
} catch (Exception ex) {
s_logger.warn("synchronize service-instances", ex);
return false;
}
return inSync;
}
}