/* Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Collections.Generic; using XenAdmin.Wizards.NewNetworkWizard_Pages; using XenAPI; using XenAdmin.Core; using XenAdmin.Actions; using XenAdmin.Controls; namespace XenAdmin.Wizards { public enum NetworkTypes { Internal, // old-style (host-only) private networks CHIN, // cross-host internal (or private) networks External, Bonded, SRIOV } public partial class NewNetworkWizard : XenWizardBase { private readonly NetWTypeSelect pageNetworkType; private readonly NetWName pageName; private readonly NetWDetails pageNetworkDetails; private readonly NetWBondDetails pageBondDetails; private readonly NetWChinDetails pageChinDetails; private readonly NetWSriovDetails pageSriovDetails; /// /// May be null. /// private readonly Pool Pool; private readonly Host Host; private NetworkTypes? m_networkType; /// /// /// /// /// May be null. /// Never null. In the case of a pool, "host" is set to the master. public NewNetworkWizard(Network.IXenConnection connection, Pool pool, Host host) : base(connection) { InitializeComponent(); pageNetworkType = new NetWTypeSelect(); pageName = new NetWName(); pageNetworkDetails = new NetWDetails(); pageBondDetails = new NetWBondDetails(); pageChinDetails = new NetWChinDetails(); pageSriovDetails = new NetWSriovDetails(); System.Diagnostics.Trace.Assert(host != null); Pool = pool; Host = host; if (Pool != null) pageBondDetails.SetPool(Pool); else pageBondDetails.SetHost(Host); pageNetworkDetails.Host = host; pageChinDetails.Host = host; pageChinDetails.Pool = pool; pageSriovDetails.Host = host; AddPage(pageNetworkType); AddPage(new XenTabPage { Text = "" }); } protected override void OnShown(EventArgs e) { Text = string.Format(Messages.NEWNETWORKWIZARD_TITLE, Helpers.GetName(xenConnection)); base.OnShown(e); } protected override void UpdateWizardContent(XenTabPage senderPage) { var prevPageType = senderPage.GetType(); if (prevPageType == typeof(NetWTypeSelect)) { var oldNetworkType = m_networkType; m_networkType = pageNetworkType.SelectedNetworkType;//value non-null, so safe to cast further below RemovePagesFrom(1); if (m_networkType == NetworkTypes.Bonded) { AddPage(pageBondDetails); } else { AddPage(pageName); pageName.SelectedNetworkType = (NetworkTypes)m_networkType; if (oldNetworkType != m_networkType) NotifyNextPagesOfChange(pageName); if (m_networkType == NetworkTypes.CHIN) AddPage(pageChinDetails); else if (m_networkType == NetworkTypes.SRIOV) { AddPage(pageSriovDetails); } else { AddPage(pageNetworkDetails); pageNetworkDetails.SelectedNetworkType = (NetworkTypes)m_networkType; if (oldNetworkType != m_networkType) NotifyNextPagesOfChange(pageNetworkDetails); } } } } protected override void FinishWizard() { NetworkTypes network_type = pageNetworkType.SelectedNetworkType; switch (network_type) { case NetworkTypes.Bonded: CreateBonded(); break; case NetworkTypes.CHIN: CreateCHIN(); break; case NetworkTypes.SRIOV: CreateSRIOV(); break; default: CreateNonBonded(); break; } base.FinishWizard(); } private void CreateBonded() { new CreateBondAction(pageBondDetails.Connection, pageBondDetails.BondName, pageBondDetails.BondedPIFs, pageBondDetails.AutoPlug, pageBondDetails.MTU, pageBondDetails.BondMode, pageBondDetails.HashingAlgorithm).RunAsync(); } private void CreateCHIN() { XenAPI.Network network = CreateNetworkObject(); XenAPI.Network theInterface = pageChinDetails.SelectedInterface; new CreateChinAction(xenConnection, network, theInterface).RunAsync(); } private void CreateSRIOV() { List sriovSelectedPifs = new List(); Pool pool = Helpers.GetPoolOfOne(Host.Connection); if (pool == null) return; if (pageSriovDetails.SelectedHostNic == null) return ; foreach (PIF thePIF in pool.Connection.Cache.PIFs) { if (thePIF.IsPhysical() && !thePIF.IsBondNIC() && thePIF.SriovCapable() && thePIF.device == pageSriovDetails.SelectedHostNic.device && !thePIF.IsSriovPhysicalPIF()) sriovSelectedPifs.Add(thePIF); } XenAPI.Network network = CreateNetworkObject(); if (sriovSelectedPifs.Count != 0) new CreateSriovAction(xenConnection, network, sriovSelectedPifs).RunAsync(); } private void CreateNonBonded() { XenAPI.Network network = CreateNetworkObject(); PIF nic; if (pageNetworkDetails.CreateVlanOnSriovNetwork) { if (pageNetworkDetails.SelectedHostNic == null || !pageNetworkDetails.SelectedHostNic.IsSriovPhysicalPIF()) return; var sriovPhysicalPif = xenConnection.Resolve(pageNetworkDetails.SelectedHostNic.sriov_physical_PIF_of[0]); if (sriovPhysicalPif == null) return; nic = xenConnection.Resolve(sriovPhysicalPif.logical_PIF); if (nic == null) return; } else { nic = pageNetworkDetails.SelectedHostNic; } long vlan = pageNetworkDetails.VLAN; NetworkAction action = pageNetworkType.SelectedNetworkType == NetworkTypes.External ? new NetworkAction(xenConnection, network, nic, vlan) : new NetworkAction(xenConnection, network, true); action.RunAsync(); } private XenAPI.Network CreateNetworkObject() { XenAPI.Network result = new XenAPI.Network { name_label = pageName.NetworkName, name_description = pageName.NetworkDescription, managed = true }; var autoPlug = pageNetworkType.SelectedNetworkType == NetworkTypes.CHIN ? pageChinDetails.isAutomaticAddNicToVM : pageNetworkType.SelectedNetworkType == NetworkTypes.SRIOV ? pageSriovDetails.isAutomaticAddNicToVM : pageNetworkDetails.isAutomaticAddNicToVM; result.SetAutoPlug(autoPlug); if (pageNetworkType.SelectedNetworkType == NetworkTypes.CHIN) result.MTU = pageChinDetails.MTU; else if (pageNetworkDetails.MTU.HasValue) //Custom MTU may not be allowed if we are making a virtual network or something result.MTU = pageNetworkDetails.MTU.Value; return result; } protected override string WizardPaneHelpID() { return "NewNetworkWizard"; } } }