Cisco Logo


Data Center and Cloud

My family and I have been going to Mexico on vacation for the past twelve years, pretty much every other year we spend a week in Cancun or somewhere on the Mayan Riviera. Every time we book our trip I plan to buy a Spanish language learning course and be prepared when I get there, but never do and I’m never prepared. Not that you need to know Spanish, there’s plenty of English spoken, I just want to be better at communicating.

I’ve often thought, wouldn’t it be great if everyone spoke the same language, and then communicating would be very easy. However my children and I speak the same language, my wife and I speak the same language yet we sometimes have difficulty understanding one another. Then it comes down to nuance and semantics and properly parsing what has been communicated. What I really need is a Rosetta Stone of sorts, one that shows me what my children say and what it actually means. Even better would be one that shows the translation for what a spouse says and what is actually meant.

From a programming perspective I have often been asked “What language should I know?”, “What is the best fit?”, “What do you use?” I always answer in the same completely unambiguous way… “It depends.” Then I ask my questions. What is the programming language that your IT staff knows the best? Is that a language that has a good level of support? What OS are you comfortable on? What format is your data in? Do you already have standards that you need to adhere to? Etc…

After I pepper them with so many of my own questions and they are dizzy from the interrogation, I give them my one unambiguous answer, the language of the Cloud is XML and the Rosetta Stone of the Cloud is XSLT with XPATH.

Solely my opinion, others may agree or disagree. The UCS API is XML based, other products I work with are XML based, and some new Cisco products that are coming out are building on the success of the UCS XML Data Model. I think that being fluent in XML and the methods of translating and extracting information from the XML is a top priority in speaking Cloud.

Where do I speak XML? I’m speaking XML for orchestration, automation, troubleshooting, reporting, monitoring, managing, and anything else that happens in the Cloud. If the component that is being managed is not fluent in XML now, probably one day it will be. I would take XML as close to that component as you can and when the XML fluent version comes out you’ll be well situated to speak Cloud to that component.

The UCS Manager and now the C-Series servers (non-UCS managed ones) have an XML API (so very similar to the UCS MAnager XML API). The Cisco VNMC uses an XML API and I would suspect many more Cisco products will embrace a similar XML API. Behind the UCS Manager API is the UCS Object Model AKA the Management Information Tree (MIT). The MIT is a hierarchical structure that represents both physical and logical objects in the UCS. The MIT is acted upon by the Data Management Engine (DME). The DME manages objects and mutates those objects, managing their place in the tree. How are those objects defined? XML!

Let’s look at the UCS server (UCS Managed blade or rack) and its XML representation in the MIT. To view the XML representation of a UCS object I could use the “Copy XML” selection of the context menu in UCS Manager GUI

Copy-XML

Copy XML Selection on the UCS Manager context menu

or post a query to the XML API using curl or the Firefox addon Poster. I could also use the UCS PowerTool PowerShell library Cmdlet Get-UcsBlade with the -XML flag.

Get-UcsBlade

Get-UcsBlade with the -Xml option

I like to use curl because I can pipe the output to xmlstarlet. One of the nice features of xmlstarlet is a command line switch that will take your command line input and create XSLT output. The XSLT output can then be saved and used with other tools, that perhaps don’t have a command line but can apply an XSLT file to an XML file and generate the desired output.

UCS XML defines Object Classes, the UCS XML element is the Class Name of the UCS object; the blade class name is computeBlade, the C-Series class name is computeRackUnit, these are concrete classes. There is an abstract class called computeItem that can be queried and it will return blade and rack servers. The XML element (UCS class name) is followed by attributes; these attributes represent aspects of the UCS component. Some of the aspects of a server are, associated service profile, total memory, operational power, server id(chassis/slot for a blade or number for a rack unit), uuid, original uuid, and number of cpus. Their respective attribute names are assignedToDn, totalMemory, operPower, serverId, uuid, originalUuid, and numOfCpus. There are many more aspects (attributes) of a UCS server, I recommend the Managed Object Browser, visore (http://this documentto better understand the UCS Object Model.

What would one of my blogs be without an example? If you thought “About 50% shorter” you’re correct. In previous blogs I’ve shown UCS CallHome XML and manipulated it with xmlstarlet, posted XML documents with curl and parsed the response, also with xmlstarlet. xmlstarlet is a frequent topic for me because it provides a convenient way to work with the XML. Actually it is an XSLT engine that uses XPATH to get to the elements that need to be manipulated, extracted, and transformed.

I want to query the UCS servers and display each server’s assignedToDn, serverId, operPower, totalMemory, numOfCpus, uuid, and originalUuid. Because there is an abstract class called computeItem that provides all the object attributes that I am interested in I don’t have to do two queries (one for blades and another for rack units) I can retrieve all I need with a single query to computeItem. I want the query to return only servers that have an associated service profile or a value in assignedtoDn. The UCS XML API provides a query method, configResolveClass and a filter method to only return the computeItem objects that have a value in assignedToDn. The query with the filter looks like this;

<configResolveClass cookie=”auth-cookie” inHierarchical=”false” classId=”computeItem”>
<inFilter>
<wcard class=”computeItem” property=”assignedToDn” value=”o*” />
</inFilter>
</configResolveClass>

I used the wildcard filter, wcard. If the assignedToDn property of computeItem started with an “o” then return that computeItem object. Why “o*” for a wildcard filter? Well all service profiles will reside in an organization either the root organization (org-root) or a sub organization off of org-root, therefore all service profile DNs will start with “org-root”. I can filter the returned objects at the UCS with a query filter or I can filter them with XSLT and XPATH.  As a programming guideline I almost always filter the objects using XSLT because then I don’t put that processing load on the UCS Manger/Fabric Interconnects and I always have the full object set at my disposal.  In the event I wish to display both associated and unassociated servers, I need only change my XSLT not my query code.

What would my UCS query look like without the filter?

<configResolveClass cookie=”auth-cookie” inHierarchical=”false” classId=”computeItem”/>

That’s a bit simpler, now on to the XSLT and XPATH. XSLT transforms, XPATH finds. The XSLT language allows for the transform of the found elements and their attribute values. Transform can be many things, display, recode, parse, massage, etc…

In the command below I inserted a cookie that I generated with a curl command that passed a aaaLogin method to the UCS API.

The -H parameter to curl indicates the header type, -N means non-buffered output, -s means silent and -d indicates that the next section is the XML document to send in the BODY of the HTTP POST. The last parameter to curl is the UCS URL with a path to the XML API service (/nuova). The output of the command is piped to xmlstarlet (I have compiled to xml.exe this example is run on a Windows 7 Cygwin install).

The parameters to xml.exe are sel means select mode, -t indicates template , -m means seach for the following XPATH expression, -s followed by A:T:U @dn in this example means sort dn values ascending, textually with uppercase first. Finally -v means print the value of the XPATH expression. In the example it is a concatenation of the computeBlade or computeRackUnit attributes that have been specified.

$ curl -k -H "Content-Type: text/xml" -N -s -d '<configResolveClass classId="computeItem" inHierarchical="false" cookie="1337013270/b3fd2a8e-2f10-4fec-9edc-d9b8c69da308" />' http://172.16.206.137/nuova | ./xml.exe sel -t -m "//computeBlade[@association='associated'] | //computeRackUnit" -s A:T:U @dn -v "concat(@dn, ' ', @assignedToDn, ' ', @serverId, ' ' , @operPower, ' ', @totalMemory, ' ', @numOfCpus, ' ', @uuid, ' ', @originalUuid)" –n

Running the command generated the following two lines of output, notice that the -m parameter finds either computeBlade or computeRackUnit in the returned XML from the UCS query, however only the computeBlade element will be filtered by the association attribute.

sys/chassis-1/blade-1 org-root/ls-Blade1 1/1 on 49152 2 1b4e28ba-2fa1-11d2-0101-b9a761bde3fb 1b4e28ba-2fa1-11d2-0101-b9a761bde3fb
sys/rack-unit-3  org-root/ls-RackUnit3 3 on 24576 2 00000000-0000-0000-0000-000000010000 ec99aa01-6083-11df-a54d-68efbdf66494

Running the command again but adding a -C after the sel option of xml.exe will cause the output of the command to be the XSLT that will be used to perform the transformation.

$ curl -k -H "Content-Type: text/xml" -N -s -d '<configResolveClass classId="computeItem" inHierarchical="false" cookie="1337013270/b3fd2a8e-2f10-4fec-9edc-d9b8c69da308" />' http://172.16.206.137/nuova | ./xml.exe sel -C -t -m "//computeBlade[@association='associated'] | //computeRackUnit" -s A:T:U @dn -v "concat(@dn, ' ', @assignedToDn, ' ', @serverId, ' ' , @operPower, ' ', @totalMemory, ' ', @numOfCpus, ' ', @uuid, ' ', @originalUuid)" -n

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:func="http://exslt.org/functions"
xmlns:set="http://exslt.org/sets"
xmlns:str="http://exslt.org/strings"
xmlns:dyn="http://exslt.org/dynamic"
xmlns:saxon="http://icl.com/saxon"
xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"
xmlns:xt="http://www.jclark.com/xt"
xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
xmlns:test="http://xmlsoft.org/XSLT/"
extension-element-prefixes="exslt math date func set str dyn saxon xalanredirect xt libxslt test"
exclude-result-prefixes="math str">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:param name="inputFile">-</xsl:param>
<xsl:template match="/">
<xsl:call-template name="t1"/>
</xsl:template>
<xsl:template name="t1">
<xsl:for-each select="//computeBlade[@association='associated'] | //computeRackUnit">
<xsl:sort order="ascending" data-type="text" case-order="upper-first" select="@dn"/>
<xsl:value-of select="concat(@dn, ' ', @assignedToDn, ' ', @serverId, ' ' , @operPower, ' ', @totalMemory, ' ', @numOfCpus, ' ',@uuid, ' ', @originalUuid)"/>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>

The generated XSLT can be used as input to another program. The example pulled data from the XML and displayed it, which is useful, but the power or XPATH and XSLT is transformation of XML.  Suppose that you wanted to generate XML from the query input that had the following structure to pass to another program.

<computeItems>
<computeItem dn="dn value">
<totalMemory>total memory value</totalMemory>
<numOfCpus>number of cpus</numOfCpus>
</computeItem>
</computeItems>

The following command will do the trick, notice I have removed the filtering on the association attribute. I also pass the output of the xml.exe sel command through xml.exe fo, the fo means that XML output should be formatted based on the supplied options. No options with the fo setting means pretty print the XML

$ curl -k -H "Content-Type: text/xml" -N -s -d '<configResolveClass classId="computeItem" inHierarchical="false" cookie="1337013270/b3fd2a8e-2f10-4fec-9edc-d9b8c69da308" />' http://172.16.206.137/nuova | ./xml.exe sel -t -e computeItems -m "//computeBlade | //computeRackUnit" -s A:T:U @dn -e computeItem -a dn -v @dn -b -e totalMemory -v @totalMemory -b -e numOfCpus -v @numOfCpus | ./xml fo

Here is the output

<?xml version="1.0"?>
<computeItems>
<computeItem dn="sys/chassis-1/blade-1">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-2">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-3">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-4">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-5">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-6">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-7">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/chassis-1/blade-8">
<totalMemory>49152</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
<computeItem dn="sys/rack-unit-3">
<totalMemory>24576</totalMemory>
<numOfCpus>2</numOfCpus>
</computeItem>
</computeItems>

And of course the XSLT that was generated by using the -C option after “sel” in the  xml.exe command

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" xmlns:math="http://exslt.org/
math" xmlns:date="http://exslt.org/dates-and-times" xmlns:func="http://exslt.org/functions" xmlns:set="http://exslt.org/sets" xmlns:
str="http://exslt.org/strings" xmlns:dyn="http://exslt.org/dynamic" xmlns:saxon="http://icl.com/saxon" xmlns:xalanredirect="org.apac
he.xalan.xslt.extensions.Redirect" xmlns:xt="http://www.jclark.com/xt" xmlns:libxslt="http://xmlsoft.org/XSLT/namespace" xmlns:test=
"http://xmlsoft.org/XSLT/" version="1.0" extension-element-prefixes="exslt math date func set str dyn saxon xalanredirect xt libxslt
test" exclude-result-prefixes="math str">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:param name="inputFile">-</xsl:param>
<xsl:template match="/">
<xsl:call-template name="t1"/>
</xsl:template>
<xsl:template name="t1">
<xsl:element name="computeItems">
<xsl:for-each select="//computeBlade | //computeRackUnit">
<xsl:sort order="ascending" data-type="text" case-order="upper-first" select="@dn"/>
<xsl:element name="computeItem">
<xsl:attribute name="dn">
<xsl:value-of select="@dn"/>
</xsl:attribute>
<xsl:element name="totalMemory">
<xsl:value-of select="@totalMemory"/>
</xsl:element>
<xsl:element name="numOfCpus">
<xsl:value-of select="@numOfCpus"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

As a developer using whatever tools you do to get the job done you may be abstracted from the XML, but I believe that at some point you will need to understand XML and need to be able to search, manipulate and transform XML, if you want to speak Cloud.

In an effort to keep conversations fresh, Cisco Blogs closes comments after 90 days. Please visit the Cisco Blogs hub page for the latest content.

2 Comments.


  1. Interesting article. While I also agree that XML is a hugely important format, I was just thinking about how little I run into it in my daily work any more. Maybe it’s just because all of the XML stuff we do is “finished”, as in doesn’t need work very often and functions properly. But it also seems that more and more of the data I work with is one-time downloads in CSV, etc. put into a database, and then worked on. While most user-generated stuff comes in JSON from the web.

    Interesting post though!

       1 like

    • John McDonough
      John McDonough

      Hi Nathan,

      I appreciate the comments, I’m coming from the point of view that cloud components all need to speak to each other for orchestration and automation. At Cisco and with other companies’ cloud products I’m seeing a trend to XML. While developers may be abstracted from the XML I believe that to really understand the communications between components and to troubleshoot, XML will need to be part of your vocabulary.

      Regards,
      John

         1 like

  1. Return to Countries/Regions
  2. Return to Home
  1. All Data Center and Cloud
  2. All Security
  3. Return to Home