diff --git a/XenAdmin/TabPages/GeneralTabPage.cs b/XenAdmin/TabPages/GeneralTabPage.cs index bb7390e69..50fa45830 100644 --- a/XenAdmin/TabPages/GeneralTabPage.cs +++ b/XenAdmin/TabPages/GeneralTabPage.cs @@ -1372,7 +1372,8 @@ namespace XenAdmin.TabPages s.AddEntry(Messages.CONTAINER_IMAGE, dockerContainer.image.Length != 0 ? dockerContainer.image : Messages.NONE); s.AddEntry(Messages.CONTAINER, dockerContainer.container.Length != 0 ? dockerContainer.container : Messages.NONE); s.AddEntry(Messages.CONTAINER_COMMAND, dockerContainer.command.Length != 0 ? dockerContainer.command : Messages.NONE); - s.AddEntry(Messages.CONTAINER_PORTS, dockerContainer.ports.Length != 0 ? dockerContainer.ports : Messages.NONE); + var ports = dockerContainer.PortList.Select(p => p.Description); + s.AddEntry(Messages.CONTAINER_PORTS, ports.Count() != 0 ? string.Join("\n", ports) : Messages.NONE); s.AddEntry(Messages.UUID, dockerContainer.uuid.Length != 0 ? dockerContainer.uuid : Messages.NONE); } } diff --git a/XenModel/DockerContainer.cs b/XenModel/DockerContainer.cs index d7fad62fe..12702fecf 100644 --- a/XenModel/DockerContainer.cs +++ b/XenModel/DockerContainer.cs @@ -30,6 +30,8 @@ */ using System; +using System.Collections.Generic; +using System.Xml; using XenAPI; using XenAdmin.Core; @@ -302,5 +304,71 @@ namespace XenAdmin.Model return string.Format(Messages.CONTAINER_ON_VM_TITLE, Name, parent.Name, parent.LocationString); } } + + public List PortList + { + get + { + var portList = new List(); + if (string.IsNullOrEmpty(ports)) + return portList; + + var xmlDoc = new XmlDocument(); + try + { + xmlDoc.LoadXml("" + ports + ""); // wrap the ports into a root node + var items = xmlDoc.GetElementsByTagName("item"); + + foreach (XmlNode node in items) + { + var item = new DockerContainerPort(); + foreach (XmlNode child in node.ChildNodes) + { + switch (child.Name) + { + case "IP": + item.Address = child.InnerText; + break; + case "PublicPort": + item.PublicPort = child.InnerText; + break; + case "PrivatePort": + item.PrivatePort = child.InnerText; + break; + case "Type": + item.Protocol = child.InnerText; + break; + } + } + portList.Add(item); + } + } + catch { } + return portList; + } + } + + public struct DockerContainerPort + { + public string Address, PublicPort, PrivatePort, Protocol; + + public string Description + { + get + { + var list = new List(); + if (!string.IsNullOrEmpty(Address)) + list.Add(string.Format(Messages.CONTAINER_PORTS_ADDRESS, Address)); + if (!string.IsNullOrEmpty(PublicPort)) + list.Add(string.Format(Messages.CONTAINER_PORTS_PUBLIC_PORT, PublicPort)); + if (!string.IsNullOrEmpty(PrivatePort)) + list.Add(string.Format(Messages.CONTAINER_PORTS_PRIVATE_PORT, PrivatePort)); + if (!string.IsNullOrEmpty(Protocol)) + list.Add(string.Format(Messages.CONTAINER_PORTS_PROTOCOL, Protocol)); + return string.Join("; ", list); + } + } + } + } } diff --git a/XenModel/DockerContainers.cs b/XenModel/DockerContainers.cs index 64ba7913c..971e0ba14 100644 --- a/XenModel/DockerContainers.cs +++ b/XenModel/DockerContainers.cs @@ -230,7 +230,7 @@ namespace XenAdmin.Model string ports = ""; propertyNode = entry.ChildNodes.Cast().FirstOrDefault(node => node.Name == "ports"); if (propertyNode != null) - ports = propertyNode.InnerText; + ports = propertyNode.InnerXml; DockerContainer newContainer = new DockerContainer(vm, id, name, string.Empty, status, container, created, image, command, ports); diff --git a/XenModel/Messages.Designer.cs b/XenModel/Messages.Designer.cs index e082fa499..87ec8cca3 100644 --- a/XenModel/Messages.Designer.cs +++ b/XenModel/Messages.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -7878,6 +7878,42 @@ namespace XenAdmin { } } + /// + /// Looks up a localized string similar to Address: {0}. + /// + public static string CONTAINER_PORTS_ADDRESS { + get { + return ResourceManager.GetString("CONTAINER_PORTS_ADDRESS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Private port: {0}. + /// + public static string CONTAINER_PORTS_PRIVATE_PORT { + get { + return ResourceManager.GetString("CONTAINER_PORTS_PRIVATE_PORT", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Protocol: {0}. + /// + public static string CONTAINER_PORTS_PROTOCOL { + get { + return ResourceManager.GetString("CONTAINER_PORTS_PROTOCOL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Public port: {0}. + /// + public static string CONTAINER_PORTS_PUBLIC_PORT { + get { + return ResourceManager.GetString("CONTAINER_PORTS_PUBLIC_PORT", resourceCulture); + } + } + /// /// Looks up a localized string similar to contains. /// diff --git a/XenModel/Messages.resx b/XenModel/Messages.resx index ede2a15cd..086dc0fb6 100755 --- a/XenModel/Messages.resx +++ b/XenModel/Messages.resx @@ -2840,14 +2840,26 @@ You can only connect to a single Citrix XenServer Express Edition server at a ti Container General Properties + + Image + {0} on '{1}' {2} Ports - - Image + + Address: {0} + + + Private port: {0} + + + Protocol: {0} + + + Public port: {0} contains