/// <summary> /// This function is responsible to synchronize the network configuration between ODL and SCVMM. /// </summary> /// <param name="vtns">List of VTNs on ODL.</param> /// <param name="vMNetworkConfig">VMNetwork.config file instance.</param> /// <param name="logicalNetworkId">Logical network ID.</param> /// <param name="logicalNetworkDefinitionId">Logical network definition ID.</param> /// <param name="txnMng">Transaction manager instance.</param> /// <param name="VtnHostName">Host name of the VTNCoordinator.</param> private void CompareVTNObjects(List <Vtn> vtns, VMNetworkConfig vMNetworkConfig, Guid logicalNetworkId, Guid?logicalNetworkDefinitionId, TransactionManager txnMng, string VtnHostName) { var vmnetworks = vMNetworkConfig.VMNetwork; foreach (Vtn vtn in vtns) { var vmnetworkInfo = vmnetworks.VMNetworkMappingInformation.VMNetworkInfo.FirstOrDefault(vmnet => vmnet.VTNName.Equals(vtn.Name)); if (vmnetworkInfo != null) { VMNetwork vmnetwork = vmnetworks.VmNetworks.FirstOrDefault(vmn => vmn.Id == vmnetworkInfo.VMNetworkID); this.SyncVTN(logicalNetworkDefinitionId, vmnetwork, vtn, vmnetworkInfo, txnMng, VtnHostName); } else { VMNetwork vMNetwork = VSEMVMNetworkManagement.CreateVtnVmNetwork(vtn.Name); vMNetwork.LogicalNetwork = logicalNetworkId; vMNetworkConfig.VMNetwork.VmNetworks.Add(vMNetwork); if (vMNetworkConfig.VMNetwork.VMNetworkMappingInformation.VMNetworkInfo == null) { vMNetworkConfig.VMNetwork.VMNetworkMappingInformation.VMNetworkInfo = new List <VMNetworkInfo>(); } var vmnetInfo = new VMNetworkInfo { VMNetworkID = vMNetwork.Id, VMNetworkName = string.Empty, VTNName = vtn.Name, VMSubnetInfo = new List <VMSubnetInfo>(), CreatedFrom = "ODL", Description = "VM Network corresponding to this VTN is not created on SCVMM", VMNetworkOriginalName = vMNetwork.Name }; vMNetworkConfig.VMNetwork.VMNetworkMappingInformation.VMNetworkInfo.Add( vmnetInfo); foreach (Vbridge vbr in vtn.Vbridges) { this.AddVMSubnet(vmnetInfo, vbr, vMNetwork, logicalNetworkDefinitionId); } ////--------VTN is added on ODL } } }
/// <summary> /// This function is responsible for creating a VM Network /// with one VM Subnet on the VSEM. /// </summary> protected override void DoODLVSEMCmdlet() { var JavaScriptSerializer = new JavaScriptSerializer(); JavaScriptSerializer.MaxJsonLength = int.MaxValue; StringBuilder json = new StringBuilder(" \"IPSubnets\":" + JavaScriptSerializer.Serialize(this.IPSubnets)); json.Append("\"MaxNumberOfPorts\":\"" + this.MaxNumberOfPorts + "\""); json.Append("\"VMSubnetName\":\"" + this.VMSubnetName + "\""); json.Append("\"VMNetworkName\":\"" + this.VMNetworkName + "\""); json.Append("\"LogicalNetworkDefinitionId\":\"" + this.LogicalNetworkDefinitionId + "\""); ODLVSEMETW.EventWriteDoCmdlet(this.CmdletName, "VM Network creation process started.", json.ToString()); TransactionManager txnMng = new TransactionManager(); txnMng.StartTransaction(); var ope = TransactionManager.Operation.None; VMNetwork nw = null; string vtnName = string.Empty; string connectionString = this.conn.ConnectionString.Split(',').FirstOrDefault(); VSEMVMNetworkManagement vSEMVmNetworkManagement = new VSEMVMNetworkManagement(connectionString, this.conn.Credential); try { nw = vSEMVmNetworkManagement.CreateVMNetwork(txnMng, this.VMSubnetName, this.VMNetworkName, this.MaxNumberOfPorts, this.IPSubnets, this.LogicalNetworkDefinitionId, this.conn, out vtnName); ODLVSEMETW.EventWriteReturnLibrary("VM network is created.", string.Empty); ope = TransactionManager.Operation.Commit; } catch (Exception ex) { Exception userException = ex; ODLVSEMETW.EventWriteFailedCmdlet( "VM network creation is failed. ODL changes rollback is started.", string.Empty); ope = TransactionManager.Operation.Rollback; try { if (!string.IsNullOrEmpty(vtnName)) { vSEMVmNetworkManagement.RemoveVmNetwork(vtnName); ODLVSEMETW.EventWriteFailedCmdlet( "VM network creation is failed. ODL changes are successfully rolled back.", string.Empty); } } catch (Exception except) { ODLVSEMETW.EventWriteFailedCmdlet( string.Format(CultureInfo.CurrentCulture, "Due to some problem in connection with ODL, VSEM VM Network creation process is terminated in the middle of the request. VTN '{0}' may have been created on ODL, Please check. Please delete the VTN from ODL to maintain the consistency between ODL and SCVMM.\n{1}", vtnName, except.Message), string.Empty); userException = new System.Net.WebException(string.Format(CultureInfo.CurrentCulture, "Due to some problem in connection with ODL, VSEM VM Network creation process is terminated in the middle of the request. VTN '{0}' may have been created on ODL, Please check. Please delete the VTN from ODL to maintain the consistency between ODL and SCVMM.", vtnName), ex); } Exception exception = VSEMODLExceptionUtil.ConvertExceptionToVSEMException(userException); ODLVSEMETW.EventWriteFailedCmdlet(this.CmdletName, exception.GetType() + " : " + ex.Message); ope = TransactionManager.Operation.Rollback; throw exception; } finally { txnMng.EndTransaction(ope); string output = "\"VM Network\":" + JavaScriptSerializer.Serialize(nw); ODLVSEMETW.EventWriteEndCmdlet(this.CmdletName, output); this.WriteObject(nw); } }
/// <summary> /// Remove the specified VM Subnet. /// </summary> /// <param name="txnMng">Transaction manager.</param> /// <param name="id">ID of VM Subnet to remove.</param> /// <param name="connection">VSEM connection.</param> /// <param name="vbrName">Name of the vBridge.</param> /// <returns>Indicated the need to refresh the network service..</returns> public bool RemoveVmNetworkDefinition(TransactionManager txnMng, Guid id, VSEMConnection connection, out string vbrName) { var JavaScriptSerializer = new JavaScriptSerializer(); JavaScriptSerializer.MaxJsonLength = int.MaxValue; StringBuilder json = new StringBuilder("\"txnMng\":" + JavaScriptSerializer.Serialize(txnMng)); json.Append("\"id\":\"" + id + "\""); ODLVSEMETW.EventWriteStartLibrary(MethodBase.GetCurrentMethod().Name, json.ToString()); if (txnMng == null) { ODLVSEMETW.EventWriteArgumentError( MethodBase.GetCurrentMethod().DeclaringType.Name.ToString(), MethodBase.GetCurrentMethod().Name, "The parameter 'txnMng' is null or invalid."); throw new ArgumentException("The parameter 'txnMng' is null or invalid."); } if (id == Guid.Empty) { ODLVSEMETW.EventWriteArgumentError( MethodBase.GetCurrentMethod().DeclaringType.Name.ToString(), MethodBase.GetCurrentMethod().Name, "The parameter 'id' is null or invalid."); throw new ArgumentException("The parameter 'id' is null or invalid."); } if (connection == null) { ODLVSEMETW.EventWriteArgumentError( MethodBase.GetCurrentMethod().DeclaringType.Name.ToString(), MethodBase.GetCurrentMethod().Name, "The parameter 'connection' is null or invalid."); throw new ArgumentException("The parameter 'connection' is null or invalid."); } string VtnHostName = this.ConnectionString; if (VtnHostName.StartsWith(@"https://", StringComparison.Ordinal)) { VtnHostName = VtnHostName.Substring(8); } VtnHostName = VtnHostName.Split('.', ':').First(); var vMNetworkConfig = new VMNetworkConfig(VtnHostName); txnMng.SetConfigManager(vMNetworkConfig, TransactionManager.OpenMode.WriteMode); if (vMNetworkConfig.VMNetwork.VMNetworkMappingInformation.VMNetworkInfo.Count == 0) { ODLVSEMETW.EventWriteConfigManagerFileIOError( MethodBase.GetCurrentMethod().Name, string.Format(CultureInfo.CurrentCulture, "VMNetwork.config {0}", configFileIOErrorValidationMessage)); throw new InvalidOperationException( string.Format(CultureInfo.CurrentCulture, "VMNetwork.config {0}", configFileIOErrorValidationMessage)); } string vtnName = string.Empty; vbrName = string.Empty; Guid vmNetId = Guid.Empty; VMNetworkInfo vmnetworkMappigInfoFound = null; long vlanId = 0; foreach (var vmNet in vMNetworkConfig.VMNetwork.VMNetworkMappingInformation.VMNetworkInfo) { foreach (var vmSubNet in vmNet.VMSubnetInfo) { if (vmSubNet.VMSubnetID == id) { vtnName = vmNet.VTNName; vbrName = vmSubNet.VBridgeName; vmNetId = vmNet.VMNetworkID; vlanId = vmSubNet.VBridgeVlanId; vmnetworkMappigInfoFound = vmNet; break; } } if (!string.IsNullOrEmpty(vtnName)) { break; } } if (string.IsNullOrEmpty(vbrName)) { ODLVSEMETW.EventWriteGetVSEMVMNetworkError( MethodBase.GetCurrentMethod().Name, string.Format(CultureInfo.CurrentCulture, "VMSubnet '{0}' not found.", id.ToString("B"))); throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "VMSubnet '{0}' not found.", id.ToString("B"))); } VMNetwork network = null; foreach (var vmNet in vMNetworkConfig.VMNetwork.VmNetworks) { if (vmNet.Id == vmNetId) { network = vmNet; break; } } if (network == null || !network.VMSubnets.Any(vms => vms.Id.CompareTo(id) == 0)) { ODLVSEMETW.EventWriteGetVSEMVMNetworkError( MethodBase.GetCurrentMethod().Name, string.Format(CultureInfo.CurrentCulture, "VMSubnet '{0}' not found.", id.ToString("B"))); throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "VMSubnet '{0}' not found.", id.ToString("B"))); } var logicalNetworkDefinitionId = vMNetworkConfig.VMNetwork.VmNetworks.FirstOrDefault( vmn => vmn.Id == vmNetId).VMSubnets.FirstOrDefault( subNetwork => subNetwork.Id == id).LogicalNetworkDefinitionId; VSEMSynchronization vSEMSynchronization = new VSEMSynchronization(this.ConnectionString, this.Credential); Controller odl = new Controller(this.ConnectionString, this.Credential); List<Vtn> vtns = odl.ReadVTNObjects(vtnName); if (vtns.Count == 0 && network.VMSubnets.Count() > 1) { ODLVSEMETW.EventWriteValidateVMNetDefinitionError( MethodBase.GetCurrentMethod().Name, "Corresponding VTN is not found on ODL."); throw new DataMisalignedException( "Corresponding VTN is not found on ODL.\nRefresh the Odl configuration and then retry."); } string vbridgeName = vbrName; if (vtns[0].Vbridges.Any(vbr => vbr.Name.CompareTo(vbridgeName) != 0) && network.VMSubnets.Count() == 1) { ODLVSEMETW.EventWriteValidateVMNetDefinitionError( MethodBase.GetCurrentMethod().Name, "On synchronization, additional vBridge(s) are found in the VTN corresponding to this VM Network on ODL.\nSo, this VM Network cannot be removed and the operation has been abandoned.\nRefresh the Odl configuration and then retry."); throw new DataMisalignedException( "On synchronization, additional vBridge(s) are found in the VTN corresponding to this VM Network on ODL.\nSo, this VM Network cannot be removed and the operation has been abandoned.\nRefresh the Odl configuration and then retry."); } Vbridge vbridge = vtns[0].Vbridges.FirstOrDefault(vbr => vbr.Name.CompareTo(vbridgeName) == 0); if (vbridge != null && vlanId != vbridge.VlanId) { ODLVSEMETW.EventWriteValidateVMNetDefinitionError( MethodBase.GetCurrentMethod().Name, "VLAN ID of corresponding vBridge is modified on ODL."); throw new DataMisalignedException( "VLAN ID of corresponding vBridge is modified on ODL.\nRefresh the Odl configuration and then retry."); } var vmsubnet = vmnetworkMappigInfoFound.VMSubnetInfo.Where(vms => vms.VMSubnetID.CompareTo(id) == 0).First(); if (vmsubnet.CreatedFrom.Contains("ODL") && vbridge != null) { ODLVSEMETW.EventWriteGetVSEMVMNetworkError( MethodBase.GetCurrentMethod().Name, "Corresponding vBridge is created or modified on ODL"); throw new DataMisalignedException("Corresponding vBridge is created or modified on ODL.\nRefresh the Odl configuration and then retry."); } if (vtns.Count != 0) { Vbridge vBridge = new Vbridge(this.ConnectionString, this.Credential); vBridge.RemoveVbridge(vtnName, vbrName); ODLVSEMETW.EventWriteReturnODLLibrary("Return from ODL Library.", string.Empty); } // Checking if VM Network removal is required. network.VMSubnets = network.VMSubnets.Where( netDef => netDef.Id != id).ToArray(); vmnetworkMappigInfoFound.VMSubnetInfo.RemoveAll(subNet => subNet.VMSubnetID == id); if (network.VMSubnets.Count() == 0) { VSEMVMNetworkManagement vmNetworkManagement = new VSEMVMNetworkManagement(this.ConnectionString, this.Credential); vmNetworkManagement.RemoveVmNetwork(vMNetworkConfig, vmNetId); } odl.UpdateStartupConfiguration(); ODLVSEMETW.EventWriteReturnODLLibrary("Return from ODL Library.", string.Empty); ODLVSEMETW.EventWriteEndLibrary(MethodBase.GetCurrentMethod().Name, string.Empty); return false; }