7. Object Model
• Contains a modeled
representation of:
• Application
• Network
• Services
• Virtualization
• Management
Root
Policy
Universe
Tenants
Application
s
Infra
VLANs
Topology
Nodes
Virtual
Network
Hypervisors
8. Objects within APIC are structured in tree-
based hierarchy
Objects referred to as “managed objects” (MO)
Packages identify the functional area
e.g., fv = fabric virtualization, vz = virtual zones,
fabric = physical fabric, etc
Every object has a parent, with exception of
top:Root (top of tree)
Relationships exist between objects
Management Information Tree (MIT)
9. Managed Objects
Root
Everything is an object
Objects are hierarchically organized
Class identifies object type
Card, Port, Path, EPG…
Class Inheritance
Access port is a subclass of port.
A leaf node is a subclass of fabric node.
Set of attributes
identity states descriptions
references lifecycle
MO
• class
• dn
• prop1
• prop2, etc
Distributed Managed Information Tree (dMIT) contains
comprehensive system information
• discovered components
• system configuration
• operational status including statistics and faults
dMIT
Full unified description of entities.
No artificial separation of configuration, state,
runtime data.
10. Management Information Tree Example
topRoot
polUni fvTenant
fvAp fvAEPg
vzFilter vzEntry
vzBrCP vzSubj
fabricTopolog
y
fabricPod
fabricPathEp
Cont
fabricPathEp
fabricNode
vmmProvP vmmDomP vmmCtrlrP
11. DN is used as a globally unique identifier for an object in the MIT
Formed by getting relative name (RN) and appending it to parent RN until reaching topRoot
RN naming rule depends on object
Can be found in APIC model documentation
Distinguished Name
topRoot
polUni fvTenant
fvAp fvAEPg
vzFilter vzEntry
vzBrCP vzSubj
fabricTopology fabricPod
fabricPathEpCont fabricPathEp
fabricNode
vmmProvP vmmDomP vmmCtrlrP
Example:
EPG in a tenant named “tenant” under
application “app1”
uni/tn-tenant/ap-app1/epg-epg1
Example:
Interface Eth1/3 on leaf 102 in pod 1
topology/pod-1/paths-102/pathep-[eth1/3]
13. Standard REST methods supported
REST API: Basics
Method Action Behavior
POST Create / Update Idempotent
GET Read Nullipotent
DELETE Delete Idempotent
• Payloads can be either XML or JSON
Specified by the file extension in URI
Content-Type and Accept header is ignored
14. REST API: Read Operations
/api
API
Operator
/{mo|class}
Specify
Managed
Object or Class
Operator
/{dn|classname}
Distinguished
name or Object
Class
.{xml|json}
Encoding for
response
?[options]
Specify filters,
selectors or
modifiers to query,
joined using
ampersand (&)
host:port
APIC host
and port
http(s)://
http or https
protocol
http://apic/api/mo/uni/tn-Cisco/ap-Software/epg-Download.xml
Read properties for an EPG by Distinguished Name
http://apic/api/class/l1PhysIf.xml?query-target-filter=eq(l1PhysIf.speed,"10G")
Find all 10G ports on Fabric
15. REST API: Create/Update Operations
/api /mo /dn .{xml|json} ?[options]host:porthttp(s)://
<fvTenant name="NewTenant">
<fvAp name="NewApplication">
<fvAEPg name="WebTier">
<fvRsPathAtt encap="vlan-1" mode="regular"
tDn="topology/pod-1/paths-17/pathep-[eth1/1]"/>
</fvAEPg>
</fvAp>
</fvTenant>
Payload is XML/JSON representation of API Command Body
16. URI (can optionally use JSON as well – examples in upcoming slides)
http://<apic>/api/mo/aaaLogin.xml
Payload
<aaaUser name='admin' pwd='insieme'/>
Response contains a cookie named APIC-cookie, which is also mirrored in the
payload of the response under /imdata/aaaLogin/@token
<?xml version="1.0" encoding="UTF-8"?>
<imdata>
<aaaLogin
token="WkrrC6t9Vdr0U/RaftIrgFqm2phiUEstut5iiuqD74Wa6YPTlkqhoTD4e0fdOxUlT+vCcBYMp/3JFboTgdetQrNV7zklSjTvxUdOZV1yC++Klq
DykJuDgIN4bIHmJaId">
<!-- Truncated ->
</aaaLogin>
</imdata>
Use this APIC-cookie in future requests to have them authenticated
REST API: Authentication
17. Flexible Queries
By Class
By Distinguished Name
Hierarchical
Filterable
Class – Query for all objects of a certain type (e.g., all physical interfaces, then filter by speed 10G)
http://apic/api/class/l1PhysIf.xml
http://apic/api/class/l1PhysIf.xml?query-target-filter=eq(l1PhysIf.speed, "10G”)
DN – Query a specific object by its distinguished name
http://apic/api/mo/uni/tn-common.xml
Filter options:
query-target={self | children | subtree} # which object to query
query-target-filter=filter # filter to apply to query
query-target-filter=wcard(fvTenant.description,"coke.*”) # filter with regex
target-subtree-class=mo-class1,mo-class2 # what subtree objets to include
rsp-subtree={no | full | subtree } # what objects to include in response
rsp-subtree-class=mo-class # only include this class in subtree
REST API: Queries
18. Object Browser: Visore
• APIC has built in object
browser to navigate the object
tree and inspect the state of
objects
• Point the web browser to
Visore:
http://<apic>/visore.html
• Search for a particular object
or dn (fvTenant, topSystem,
topology/pod-1/node-101)
19. www.getpostman.com
Chrome plugin that enables rapid testing of REST based queries
GET request to http://apic/api/class/fvTenant.xml will return the object
configuration for all fvTenant classes
GET request to http://apic/api/mo/uni/tn-common.xml will return the
specific object referenced by DN uni/tn-common as XML
POST request to http://apic/api/mo/uni/.xml with a payload will create a
tenant.
<fvTenant name="test"/>
DELETE request to http://apic/api/mo/uni/tn-test.xml will delete
tenant test. Deletes tenant and children
POSTman
21. Cobra is a native Python language binding for APIC REST API
Supports lookups, creations, modifications, deletions
Objects in Cobra are a 1:1 representation of objects in the MIT
As a result, policy created via GUI/JSON/XML can be used as a programming
template, for more rapid development
All data has client side consistency checks performed
Packaged as .egg, install with easy_install
ACI SDK: Cobra
22. Getting started: Logging in
import cobra.mit.access
import cobra.mit.session
ls = cobra.mit.session.LoginSession(
'http://apic', 'username', 'password')
md = cobra.mit.access.MoDirectory(ls)
md.login()
Link the
credentials to
the APIC
Define an APIC
to which we
will login
LoginSession
stores URI
and
credentials
23. Getting started: Object Lookup
uniMo = md.lookupByDn('uni')
• lookupByDn
• Look up a restaurant by street address
(find me the restaurant at 1335 N 1st
Street, San Jose, CA)
• lookupByClass
• Look up a restaurant by cuisine (find
me any Japanese restaurants)
uniMo = md.lookupByClass('polUni')
24. Getting started: Object Creation
import cobra.model.fabric
# Advice: Don’t hardcode Dn’s.
topMo = md.lookupByDn('uni/controller/nodeidentpol')
leaf1IdentP = cobra.model.fabric.NodeIdentP(
topMo, serial='TEP-1-17', nodeId='17', name='leaf1')
spine1IdentP = cobra.model.fabric.NodeIdentP(
topMo, serial='TEP-1-19', nodeId='19', name='spine1')
Use Visore to
find the class
Note – These objects are created locally only,
to save them to the APIC use a
ConfigRequest.
25. Getting started: Committing configuration
import cobra.mit.request
topMo = md.lookupByClass('fabricNodeIdentPol')[0]
# Dn is no longer hard coded.
leaf1IdentP = cobra.model.fabric.NodeIdentP(
topMo, serial='TEP-1-17', nodeId='17', name='leaf1')
spine1IdentP = cobra.model.fabric.NodeIdentP(
topMo, serial='TEP-1-19', nodeId='19', name='spine1')
c = cobra.mit.request.ConfigRequest()
c.addMo(topMo) # Add and commit the most top level object that makes sense
md.commit(c)
Change a hard coded Dn
into a lookupByClass() call
26. from cobra.model.fv import Tenant
from cobra.model.pol import Uni
from cobra.mit.request import ConfigRequest
uniMo = Uni('') # Uni is a static Mo, so we don’t need to look it up
t = Tenant(uniMo, 'Tenant1') # We create a tenant as a child of the universe
c = ConfigRequest() # Create a ConfigRequest to contain our new object
c.addMo(t) # Add our tenant to the ConfigRequest
moDir.commit(c) # Commit our configuration request
Create a tenant
27. from cobra.model.fv import *
from cobra.model.pol import Uni
uniMo = Uni('')
t = Tenant(uniMo, 'Tenant1')
ap = Ap(t, 'Exchange')
epg1 = AEPg(ap, 'OWA')
epg2 = AEPg(ap, 'FrontEnd')
epg3 = AEPg(ap, 'MailBox')
ep = RsPathAtt(epg1, tDn=‘topology/pod-1/paths-17/paths-[eth1/1]’,
mode=‘regular’, encap=‘vlan-10’)
c = ConfigRequest()
c.addMo(t)
moDir.commit(c)
Create a simple application
Note – Bridge Domain configuration omitted for
brevity. Please see the Cobra SDK or APIC
Configuration Guide for a complete configuration
So let me just describe a little bit about the object model. When NCME first started, a bunch of really smart guys sat down in a room. And they said, OK. Let's try to make a model of a data center. Now, how many people have CS backgrounds with you're science degrees? Right. You remember doing-- maybe you don't-- normalized forms in one of your database classes, where you have to go and try to figure out-- I have this set of data. And now, we need to go and try to figure out how to make it into some generic abstracted form. So maybe for some business problems, it might be a fairly challenging issue. Because you might have hundreds of sets of data. Now, imagine a data center where you need to reflect the richness of applications of routing protocols, of Layer 2 protocols, of any Layer 4 protocol? All of this stuff, you need to be able to model that. And these guys sat in a room for like a year and said, OK. Let's model this. And what they came up with is the ACI object model. So it's roughly 5,000 objects that reflect almost every aspect of a data center that you can really configure. And that includes interfaces, that includes routing protocols, VPC. All of this information is in that object model.
So what that object model looks like is really a tree based hierarchy. So at the top, we have our root, which is, if you're familiar with trees, everything comes from the root. And then from that root, we have a bunch of other packages or classes. We've got the policy universe. So any configuration that you're going to make that impacts policy on the fabric. How EPGs access one another, the references to bridge domains, that kind of information is all included in that policy universe. You have a question, Mr. French. AUDIENCE: Yeah. So I wrote an email this week saying that sites were not part of the data model. PAUL LESIAK: Like data centers, you mean? AUDIENCE: Locations sites, data centers. PAUL LESIAK: Pods are. Yeah. There's geographic location. There's also-- AUDIENCE: Where? PAUL LESIAK: What's that? AUDIENCE: Where is that here? PAUL LESIAK: I don't have this-- there's 5,000 objects in here. AUDIENCE: So geolocation is above what? Oh, I thought you meant-- PAUL LESIAK: Yeah. And what-- AUDIENCE: --not part of the hierarchy. AUDIENCE: No, it's part of the hierarchy. PAUL LESIAK: Yeah, so-- So there's a couple things, right? Geolocation, racks, that kind of information is all on a per node basis. As far as sites, they're going to leverage the pod functionality of that. So essentially, a site will be either a pod or a group of pods. But that's been thought through. That's why if you look at the object model right now and you go through and reference a port, it's always pod one. But at some point in the future, there's going to be more than just pod one. Does that help? OK. I didn't repeat the question. But I guess the mic got it, so it should be fine. So this object model, also includes information like Jim mentioned, right? Infrastructure, how you get to individual interfaces on a leaf, all of that information is represented here. So think about it today. You go onto like a Cat6k. And you say int gigabit ethernet 0/1. That is included here. But it's going to include the ID of that catalyst, the pod that it 's a member of, the fabric it's a member of. All of that information is there. Now, when we're talking about the objects, keep in mind that this is all based on object oriented programming. And within object oriented programming, you have a couple of different aspects that allow for it to be object oriented. One of those is inheritance. So as an example, an interface, what can an interface be? Somebody throw out a description of an interface. One gig. Yeah, speed. Interface speed is something, right? What else? Yeah. It could be an SVI. Does a VPC count as an interface? Yeah. Does a port channel count a one? Layer 3, port channel, all this stuff. So these are all types of interfaces. But they all probably share common attributes that interface has. One of those might be the mode, whether it's a Layer 2 or Layer 3 interface. You might have a certain subset of interfaces that have speed. Or let's just say something simple, a description. So when you take that concept of inheritance, you can have information that's very common and distribute it amongst multiple different instantiations of that, or the children of it, and not have to duplicate information. So that's one aspect of object oriented programming that is leveraged here, not inheritance, but rather containment. So an object can have a parent. An object can have children. And that's useful for defining hierarchy. So especially when we get into the tenancy model, that's a very important factor. Because you want to have a tenant. You want to have an application profile beneath that, an EPG, and then have maybe filters, entries, all of that. So having this ability to organize and structure your data in a tree based hierarchy is very, very useful, especially when you want to go and fetch information out of your fabric. So Kevin put together a script that goes and mines your controller for all of the configured tenants, the bridge domains in there, EPGs, what endpoints are attached, and then displays it in Excel spreadsheet. How easy is that to do on your network today? It's not. I mean, you have to go to a CMDB somewhere to get that. Whereas, now all that information is in APIC. And I don't know , Kevin, how long did it take you to put that script together? You don't have to worry about it. It's OK. AUDIENCE: It look less than a day. PAUL LESIAK: Yeah. I mean, it's amazing how structuring this data in a very intuitive fashion makes it very easy to work with. AUDIENCE: Just one comment on that. Because part of a recurring theme in this training has been are we going to turn into programmers and things like that. The use case and that spreadsheet isn't real sexy. It shows what's possible. But then you plant a seed in the customer's mind that says, think about how easy populating your CMDB with topology information is going to be now. Because you don't want the single source of truth to be an Excel spreadsheet. That's the problem we're trying to solve, right? PAUL LESIAK: Yeah, absolutely. And so another, I guess, branch to that topic is the fact that really what the challenge is today that I'm seeing is just coming up with the use cases. Because honestly, a majority of the use cases are great ideas when you come up with them. And then coding them is done in a heartbeat. I mean, it's not really a lot of work, especially given how simple we made a lot of this stuff. So going back to the slide, I don't want to side rail the conversation too much. We've also got relationships. So relationships are important in order to define how two items may use one another. So I might have an EPG that's going to be a member, or have a relationship to, a bridge domain. And I'm going to want to do that with multiple EPGs. Well, I guess I could say one EPG maps to one bridge domain. But I might want to have multiple EPGs per bridge domain. So you can go ahead and do that. And that's possible thanks to the ability to define relationships.
So once we have all of this information instantiated, it goes into something called the MIT, the Management Information Tree. And that's pretty much how we store all of the stuff that's in the controller. The individual leaves on that tree are called managed objects, or MOs for short. And then we have packages that organize those into some logical fashion. So earlier when I'll describing the different areas of the object oriented fashion of APIC, we've got Layer 3 protocols, we've got VPCs, all that, each of those levels of functionality has its own package within the object model. So it makes it very easy to go through there and find information, look it up, and determine what's present. So Jim, when you were looking for the site description within the object model, you were probably searching for site or something like that in the package, right? If you look for something else, like-- what's that? Location? Yeah. It's under the fabric node policy. But you know, the stuff is fairly logically organized. But you do require a secret decoder ring to get some of these package names deciphered. So you'll see some of the packages are called fvAp. And you're thinking, what is VFAP? Well, it's Fabric Virtualization Application Profile. I know, it's not very intuitive. VZ, this one took me the longest time. Because what EPGs used to be called was zones. They used to be called virtual zones. And so they never changed the name to say, hey, this is an EPG security zone. But VZ is Virtual Zone. I had a number of ideas as to what it was. But I never figured it out. Finally, one day I asked Mike Dvorkin. And he was like, oh, it is Virtual Zone. What wrong with you? So everything that we have under the object model is going to fall into that top root that I discussed, right? So pretty much the only object that's special, that doesn't have a parent, is top root.
So each of these managed objects, they have properties. They have a class, which defines what it is. They have instances, which define who they are. And then they're going to have attributes that define individual properties, let's say, about them. So as an example, I might have a VLAN block. And that VLAN block is going to have a name associated with it. But it's also going to have a starting range or a from. attribute and an ending range, or the two attribute. So I can say this VLAN block is going to include VLANs 1 through 100. So all that information is included within the class, and then the properties. Then there's this other one over here that's really small. I'm sure some of you guys can't see that. But it says DN. DN is the Distinguished Name. So remember I said the class is what it is? The DN is who it is. And I'll go over that in a little bit. So I think that's probably good for this slide.
So this is just a little bit more of a example of what the tree looks like. We've got our top root. And I've actually gone through here and shown the classes. So remember Jim was asking about how can you define multiple sites? Well, underneath top root in fabric topology, under fabric pod over here, you can have multiple instances of fabric pod. So every node in the fabric, every leaf or spine or controller, they belong to a fabric pod. And you could have multiple fabric-- well, you can't have them today. But at some point, you'll have multiple fabric pods to be able to define different data center locations potentially. At the top over here, you can see the definition of what a tenant looks like. So everybody's heard the term, yeah, we have multi-tenancy, all of that stuff. But what does that look like in the object model? Well, you can see it here. We've got policy universe. Underneath policy universe, we've got the FV Tenant class. And then under FV Tenant, you're going to find an application profile at the very top there, VFAP. You can define a filter. You can define a contract. By the way, this VZBRCP, if anybody can guess what that is, what it stands for, I'll give you an NCME sticker. I think I have some in my bag. Anybody want to take a guess? You already know what the VZ stands for. OK. AUDIENCE: I don't really have a guess. Actually, it's more of a question. Is this documented? PAUL LESIAK: Yes. This stuff is all documented. It's in the object model reference. So no guesses? OK. AUDIENCE: Bridge Domain Contract? PAUL LESIAK: Bridge Domain Contract? Close. You guys? No. You guys got the contract part. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: It is a contract, yes. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Well, the VZ, I already gave you guys that. But the BR is actually the-- what's that? AUDIENCE: Broad Com. PAUL LESIAK: Broad Com? You guys continue thinking. If anybody comes up with it, I'll give you a sticker. I don't know if that motivates a room of full grown men. No? OK. I'll give you guys sales leads. I don't know. I don't know. I'm not sure. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: No. You don't want that. All right. So this is pretty much what the actual objects look like, what you're going to be dealing with that's under the covers of what you're dealing with on a daily basis in the GUI. And really, it's good to know this. Because you can see here that there are relationships here. So as an example, the VDI use case that I was discussing earlier. For that one, you need to have everything in an EPG. Now, note here that an EPG is just a member of an application profile. An application profile cannot have policy applied to it, at least not today. So what that means is that just by grouping things into an application profile does not necessarily mean that you can apply policy to all of them. And so that sort of misunderstanding between some of the individuals who are working on that account led to a little bit of difficulty. So just knowing that this is what it means, this is what the relationships can be, that kind of information is very, very valuable. And to the question that was up here earlier about is this documented, if you look at an APIC if you have one, you can go to /doc/html. And that has the model reference document on there.
So distinguished name, right? I talked about this a little bit. Why is it important? Well, there's sort of two types of systems. Well, there's probably more, but two primarily mechanisms by which you can locate and find information-- locate and find are the same thing-- but locate and identify information within a tree based hierarchy. One is to do things based on a global unique ID. The other one is to do things based on a distinguished name. So like LDAP, as an example, uses distinguish names. SNMP uses all IDs, which are somewhat of a form of a distinguished name. VMware uses GUIDs for their information. So if you've ever worked with the VMware API, you'll note that when you go and you query information in there, you look at it. And it's just a long hexadecimal string that makes seemingly no sense to you. There's arguments for and against them. Jim, I could tell that you're going to argue against it right now. No, no, no, no. Don't say anything. I wasn't encouraging you. I could tell by the look on your face. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Right. AUDIENCE: And then you could change the name. PAUL LESIAK: Yeah. Well, do you want me to play Mike Dvorkin? AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Me too. Thank you. Thank you. OK. Good. All right, excellent. Yes. AUDIENCE: That was a comment I was going to make. How do you rationalize when we have different products using different project? It's not you're problem. PAUL LESIAK: Well, you know what? Honestly, there was a question earlier from the previous presentation I think. Oh, Cesar. You were asking it, right? Do we have something that compares all of our different models and shows how do these compare and contrast with one another? As a company, I think we need to do a better job of that. Especially if they're going to have the same product name, we can't go and have two totally different things. But I'll leave that up to you guys. Because the BU listens to you way more than they listen to me. So that's all I can say. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: So distinguished names allow for you to identify something. So essentially, think of it as the path to something in a file hierarchy. There's a couple rules, a couple concepts when we talk about distinguished names that you need to keep in mind. For one, beneath any object, its children always need to have a unique relative name. So that means that if I were to ever go to any object in this hierarchy over here, I'm never going to have a duplicate relative name from the parent to the child. It's possible that maybe under fabric topology, and then somewhere else-- I mean, I actually don't know of an example where they do have the same relative names. But it is possible that something over here and something over here might have the same relative name. So that's one rule. And this is actually a big part of how you can access the objects within the tree. Because that means that you can now go and be fairly confident that you could identify something uniquely or be 100% confident, right? So I could say I'm going to start at top root. And I want to find something that's in policy universe. So I'll go to the policy universe. I want to find a specific tenant name. Go to tenant name. Find an application profile. Go to this one. Find and EPG. Go to that one. So an example of this, right? Just what I drew with my hand there. Let's say that we have an EPG and a tenant named tenant under application profile one. This is what our distinguished name is going to look like. And what is that? It's a concatenation of all of the relative names. So we start at uni. We get to-- what do we get to? Tenant. Then we get to the application profile. Then we get to the EPG. You're probably wondering where did these names come from? Like, why is it epg-? Why is it ap-? Why is it tn-? Well, that's all documented in the model reference. It's all present there. Every class has a particular naming prefix that it utilizes. So you've got tenant. His naming prefix is tn-. And then you concatenate the naming properties with it. And that's how you get to it. Another example, right? Let's say we want to find a particular interface within the fabric. How do we get to that interface? Well, say we want to find interface 1/3 on leaf 102 in pod 1. I'm going to concatenate topology plus pod 1, plus paths 102. They call this paths 102, because what can you have here that would ever make it be like more than just one node? Anybody have an idea? Remote leafs could be something, right? How about something that could be in a data center, where an interface is going to be on more than-- two different leaves? Yeah. So VPC, exactly. So if this is a VPC, you're going to see, actually, another string here, another definition, which I can't recall. I think it's like paths container dash something or other. But in either case, that's why you have that definition there. Finally, we've got the path endpoint over here, which is really just defining that this is going to be an ethernet interface. This path endpoint could also be a port channel on a single device. So that's why they sort of have that naming prefix there. So again, what you see here is that a lot of these different naming conventions, a lot of these different concepts, are very flexible. And that's in order to reflect the flexibility of a data center, of what can be present there. Your configuration can be anywhere between dead simple to more complex than the space shuttle. Well, probably not. But you need to have some flexibility. And that's why you have these different ways of referencing things.
So any questions before I continue on the REST API? OK. So we've got all this information in the model, right? We can represent all of these different concepts within our fabric. But now we want to be able to access it. So we talked about the querying mechanism earlier, right? How do you think you get to that querying mechanism? Anybody want to take a guess? It's no longer on the screen. So you can't-- OK. It's the REST API. All right. So the rest API is just a standard RESTful based XML or JSON over HTTP interface that follows most standard REST definitions. The only thing that we're really missing from common REST is that we're not really self-documenting. But otherwise, we follow all the standard REST mechanisms.
Oh, this is duplicate. Skip that one. All right. So what are the mechanisms for accessing REST? Well, we've got a POST. We've got a GET. And we've got a DELETE. Those are the ones that we've implemented. REST also has another mechanism called a PUT. But a PUT, we've grouped it together with the POST. Because in our case, if you issue multiple POST operations with the same information, you're going to get the same results. So I can never say this word correctly. And I'm going to try now. It's a idempotent operation. I don't know. Anybody want to try to pronounce that? OK, It's a tough word. What's that? AUDIENCE: [INAUDIBLE]. PAUL LESIAK: If you guys act really good, I'll give you more Dvorkin impressions. All right. So we have a POST operation. The POST operation allows you to create objects and update them. We've got the GET operation. It allows you to read things, right? And we've got the DELETE operation. So again, if you do a POST, if you take the same information and you POST it over and over and over again, it's guaranteed to make a change only once so long as the POST remains the same. That's the definition of this word that I'm not going to try to pronounce again. Whereas, nullipotent-- or nulli-potent. Nully? I don't know, however you want to pronounce it. The GET is nullipotent, meaning that you can issue it a million times, and it's never going to make a change. And then DELETE, same thing. If I go and I say, DELETE tenant Bob, DELETE tenant Bob, DELETE tenant Bob, for one thing, I'm insane. For another, I know that it's never going to delete him more than once. Because he's not there. So it's the same thing. So the payloads for all these operations can be either in XML or JSON. If you ask me for my preference, I say XML. It seems that a lot of people in the BU are being won over by my charm. Because the SDK is going to be moving to XML shortly. The reason, other than me being charming, that I've managed to convince people is because the encoding mechanism we use for JSON is very, very, very verbose. So you end up with more information in a JSON encoded data than you get with the XML encoded data, which is the opposite of what people would expect. JSON does not use full name tags to encapsulate the data. But we managed to take it and turn it into a beast. So XML's going to be used in the SDK. But the GUI will continue to use JSON. Because it's hard to convince certain people. AUDIENCE: Just a quick question on that. PAUL LESIAK: Yes. I'm very much out of my comfort zone. But isn't Python much more aligned with JSON than it is with XML output? PAUL LESIAK: Not necessarily. Python itself is just the language. I mean, there's probably more XML parsing libraries for Python than there are JSON parsing libraries. But it's just a data encapsulation mechanism. All right. So the other object, or the point to note here, is that how the information is encoded is not dependent on the content type header, the except header, the whatever header you want. It's based on the file extension. So if you see .xml, that's whats you're going to get. If you see .json, that's what you're going to get.
All right. So this is a nicely annotated display of what your request URIs are going to look like. The first three, I'm sure we can probably ignore. Because if you go to Facebook, you've seen the HTTP. If go to Facebook you've, seen the APIC. Well, no. You haven't seen the APIC host and port. Because, I don't know. Is Facebook using APIC? But anyway, if you've got to any website, you've probably seen the host and port part. Then you start seeing URI operators or URI structure. In this case, the /api operator indicates that that is the end resource on the controller we're going to be talking to. So I'm going to be talking to /api. And that dictates that I want to access the REST API. After that, we're going to specify whether we're going to be interacting with a managed object, an MO, or a class. And I think I mentioned this twice already. But can anybody tell me the difference between the Managed Object or object level and class level in terms of querying? AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yes, thank you. I'll get you a sticker. All right. So if we want to do a what it is, then we're going to do it on a class. If we want to say who it is, we're going to do it on a Managed Object. So that's going to be one or the other. There's actually a few more that can be defined here. But that's pretty much the primary two you're going to be working with. After that, we've got the distinguished name or object class, depending on whether you're querying for an object or a class, and then the encoding, and then possibly some filter options, or not necessarily just filtering options, but options for the query string. So if you want to see an example of what that looks like, that first query on the bottom that says "read properties for an EPG by distinguished name," over there, I'm saying get me, under tenant, Cisco an application called software, and then it and EPG called download. And my returned information is going to be in XML. So note what we have here. This section right here, all the way from here to here, can anybody tell me what that is? Going from-- yes, distinguished name. Who answered that one? You? Oh, very good. Thank you. Yes, you'll get a sticker. So yeah. That's a distinguished name. So what we have here is we see that we took the HTTP, APIC, API, Managed Object. And then from UNI all the way up to download, we have our distinguished name, and then the file format that we want it in. For the next one, we're going to do a query by class. So what's going to be different here is that we obviously have class over here. But instead of having a distinguished name here, we have a class name. And this class name here is Layer 1 physical interface. So I'm going to look for all the Layer 1 physical interfaces on the fabric. But then I'm going to filter them. I'm going to say that on the target of this query, only get me Layer 1 physical interfaces where the speed is 10 gigabytes. So use your imagination for how else you could leverage this. I mean, any information that's in the object model or even in the MIT you could query using these type of mechanisms. And it is a very, very useful feature. I can go in there and say maybe find me all of the EPGs that are attached to a specific leaf or whatever else you want to find to get impact analysis, that kind of information. AUDIENCE: That seems pretty manual. Or I mean, are you expecting people to actually query APIC that way manually? PAUL LESIAK: No. No. We would hope that people use the SDK. But in a little bit, I'll show you something really cool that totally eliminates the manual part. AUDIENCE: OK. Cool. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: That's possible. Yeah. So Kevin's answer was you might have people using it directly. Because you might want to give the application owners the URL to a particular query of strings, so they can get their health string. So, yeah. That's possible. If somebody's going to go and write their own REST implementation to access the APIC, then they're probably going to need to know about this. If they're going to use the SDK that comes with APIC, then they don't need to worry about this. AUDIENCE: I think this is another challenge that we have to overcome with our customers. Because for the first two or three or maybe four or, in my case it was probably a dozen times you look at it, you're like, holy smokes this is complicated. And then at some point, it starts to click. And it's like wait a second. This is powerful. Right? Complexity becomes flexibility. And we have to get our customers moved along that pipeline efficiently. AUDIENCE: I mean, these are great examples. I just don't think you're going to be learning the interface this way, right? PAUL LESIAK: I mean, honestly I can say I learned it by experiencing it, by actually saying I need to find this information. How the hell do I find it? AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yeah. AUDIENCE: Good point. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: What does RTFM stand for? No. I'm just kidding. AUDIENCE: Wait, have you read the online help? AUDIENCE: Mine says [INAUDIBLE]. AUDIENCE: Yeah. For name it says, this is where you enter the name. Real helpful. PAUL LESIAK: But that's the type of feedback that I would strongly encourage you to give to the BU. Absolutely, say this. Because right now, all of the fault codes are being rewritten to be more descriptive. Because as they were, a lot of them were not very descriptive. So Prem said, you guys need to fix this. So now-- AUDIENCE: Every single help screen is broken. Every single one has unhelpful help. PAUL LESIAK: Bring that feedback to the BU please. AUDIENCE: Things like regex, this is where you enter the regex, not this is what the format of a regular expression should look like or anything like that. I knew that's where the regex goes. That's what the label in front of the box was telling me. PAUL LESIAK: So that's another one of the areas that they're trying to fix. But again, it really requires people to go and pinpoint it and say, hey, Fabio. This needs to be fixed. It needs to be more descriptive on this help screen on this particular thing. And if you send an email to the CSACI mailer, a lot the developers are very active on that responding, either saying no that's a dumb question, or OK, fine. We need to open a bug. AUDIENCE: OK. PAUL LESIAK: So I would encourage it. I don't know if that's the answer you want. AUDIENCE: Well, I mean, I understand that I should go to every single screen. But it's a lot easier to say every single screen I've seen is broken. So go fix them all. And then I'll go look through them. PAUL LESIAK: It's a compromise, right? If it were easy for them to fix every one of them, then it would be easy for you to highlight all of them. But it's going to be difficult for you to highlight all of the ones that need repaired. Was there another question? AUDIENCE: How would you extend the data model? PAUL LESIAK: How do you extend the data model? You don't. It's statically defined on the APIC itself. There are certain sub-trees within the data model that allow for you to define custom name value pairs. Notably, one of those is the Layer 4 through 7 services, where you have the ability to define nested hierarchy and define meta-parameters for the object. But that's not necessarily a way to extend it. It's really just how you configure something. AUDIENCE: So if you need a new class of something in the future that you haven't thought of right now, it would be waiting for the BU to update the data model before you get a release then doing a migrate in production? PAUL LESIAK: So the question is if a new class is needed, does that mean you wait for the BU to release an update? Is that correct? AUDIENCE: Yeah. And then how do you migrate what you're already got? PAUL LESIAK: OK. So I guess the best way to answer this is to sort of think about it in another form of a question. When would you need to add a new class? I guess, when you feature. PAUL LESIAK: For a new feature, right. And what does a new feature require? It requires software changes. Let's say you add new hardware. What does the new hardware require? Well, on the APIC, it's going to require a new catalog to represent the capabilities of that new hardware or just the model number, that stuff. Or I mean, you're going to need new software to represent it, so multi-site, all that stuff. It's going to require new software. So the model is packaged with the software. So that's an important thing to understand. When a new version of the software comes out, a new model comes out. But it's not something that's going to be field upgradable. Let's put it that way. AUDIENCE: Yeah. I was wondering how well it fell into kind of a DevOps model. There's been a lot of talk around that in the last couple of days. And it feels like this isn't it. This is much more a release every six months, but on the roadmap of things to come out. PAUL LESIAK: How does it fit into a DevOps model? AUDIENCE: You know how you do very quick releases over and over again into production? This doesn't feel like it. AUDIENCE: [INAUDIBLE]. AUDIENCE: The model doesn't need to change. PAUL LESIAK: Yeah. I mean, would you really want that to happen? AUDIENCE: This will happen with things like Cisco Cloud Services. PAUL LESIAK: I'm not necessarily familiar with that. Maybe it's just me. Maybe I misunderstood. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yeah. I mean, I think that for this, if we go and we tell customers every two weeks we're going to be change in the object model on you, they're going to say-- AUDIENCE: [INAUDIBLE]. Yeah. AUDIENCE: That's exactly my worry. PAUL LESIAK: Well, the way that it's been designed is that it will not change between major releases-- well, not change during a single major release. And only between major releases will there be changes. And that should always include any type of deprecation that would be necessary or for objects to be deprecated in an API as you'd expect. Jim, you're holding the mic up like you want to sat something. AUDIENCE: No. I just enjoy it. The device packages extend the data model for that device. Because OpFlex doesn't support it. But we are going to put OpFlex on service nodes, which will then extend the hierarchical data model, won't it? Because if you go into the device specification today, you can actually go into the APIC. And you can see the hierarchy of the device specification. PAUL LESIAK: That's for the device specifications for OpFlex? I'm not 100% sure. AUDIENCE: Well, those are eventually moving to OpFlex, which will mean that will be a more standard model. PAUL LESIAK: Yeah. If they go to that, then I would assume that it would change. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yeah. That's what I'm thinking that-- AUDIENCE: Might have a different object model for every service. But anyway, it's extensible. If you add new devices to the APIC, the device specification is a way of extending the data model. PAUL LESIAK: It is. But you're not really creating new classes in that case. You're really just creating new instances of existing information. So that's, I guess, sort of the differentiation between them. But, yeah. You're right. When you configure a device package and you configure those devices, yes. It is adding more information, at least depth wise, to the object model. All right. So it's 1:36. I have a little more than an hour left. Is that right? OK, good. All right.
Wait, did I already? Yeah. I went through this. Create and update operations, this is a little bit simpler than the read operations, except for the fact that you're going to have the entire payload for what you're operating on within the data of the body. So you're always going to be doing a POST or an update or a create operation on an individual object. Can anybody take a guess, or an educated guess, hypothesis, what have you, as to why we don't also support classes up here? Like think through it. What would happen if you say, OK, I want to do a create or update operation on a class? AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Well, you would be extending something. But it would be the pain that you suffer when you go and you change every single object that is of that class to a particular setting. So if I go in there and I say, change every tenant to description Bob or something like that-- AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yeah. You could do that anyway by having multiple objects within this POST operation. AUDIENCE: Oh, OK. PAUL LESIAK: But it's very granular in terms of how you access this. So can say-- AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yeah. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yes, yes, yes. But you're never going to want to do a create or an update on an entire class. Because that's just going to cause problems. AUDIENCE: [INAUDIBLE]. So in that case you would do a class query, get all of the objects that you're wanting to modify back, iterate through them, and make the appropriate modifications to each one of the objects. PAUL LESIAK: Yes. Yes, on the MO. AUDIENCE: [INAUDIBLE]. Again, my example, I can say give me all the ports. I want to put VLAN 10 with 10 gig. I can do a wide loop or full loop or whatever. But then I can just do a class. PAUL LESIAK: But the distinction there though, Cesar, is that your post operation is going to be on the particular instance of that object. You're going to get all of the ports that are on the system. But then when you're making the actual modification, you're going to be saying FVR is path attach for every single interface that results in my class query. AUDIENCE: No. I get that. The question is, like Kevin was saying, I'd get a GET, right? I get all my objects. And then say, I have to do a full loop. Instead, I can just do just one line of code, and then just be done with it. AUDIENCE: But the class is just a template really. The objects are inheriting from that class. There's nothing left in the class to configure. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: If you want to change all the ports to VLAN 10, then you need to specify all the ports. AUDIENCE: Right, exactly. PAUL LESIAK: Yeah. I mean, that was sort of like a trick question. I guess it wasn't a really good one then. Because I just confused people. But the idea is that the reason you don't have class there as an option is because you need to be-- for operations where you're changing things, where it can have an impact, you need to be very specific with those. You don't want to make it just generic. Yeah, Mike didn't like it. You're trying to get an invitation out of me, I know. AUDIENCE: What? PAUL LESIAK: You're trying to get an invitation out of me. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: All right. So the payload is going to be XML or JSON body of what you're trying to represent. Something to note here, this is something that actually took me a while to figure it out. When can you just start at an arbitrary place within the XML or the JSON hierarchy? Over here, I start at fvTenant. And fvTenant is a child of policy universe. So if I post to /mo/universe.xml, then posting fvTenant over here is going to fine. But when can I say, well, I don't want to have to include the tenant. I just want to talk to, maybe, the FVR's path attach. Well, it's really a matter of telling the controller who you're talking to. So it my DN in my post string includes UNI, tenant X, application profile Y, EPG Z, then I can directly say configure this attribute. I don't need to include all of the containing hierarchy. Whereas, if I just want to post to /.xml, which is top root, I'm going to need to include the containing tags over here, so the policy universe and fvTenant and all the other information to define the path to which I'm referring. AUDIENCE: Question. PAUL LESIAK: Yes. AUDIENCE: Is this an update or a create? PAUL LESIAK: This can be both. Right? So if there's already a tenant called new tenant and there's already an application profile called new application, but then I say create web tier over here, then it's going to be a create for this. And let's say I had another EPG over here. And I said-- well, here. Let me give a better example. Because this is probably a better one. Let's say I have this FVR's path attach-- and by the way, I'll cover this, so people aren't confused. FVR path attach is pretty much how you say switchport access VLAN. I mean, if you want to think about it in the legacy ways, that how you do it. Let's say I want to change the VLAN ID that I'm using to represent an EPG on a particular port. Let's say I already had this configured. I could send another post and change this VLAN ID operation over here. And then it will update it. It won't create a new entry for this. Because actually, the naming attribute is this TDN. So it's going to just update what's already on that one. If I change my naming attribute, then it's going to do a creation. AUDIENCE: I was just looking for if you're trying to create this object or MO, what is the type that you're using to create? What is the class that you're trying to use? when you're creating it? PAUL LESIAK: The class name is always this first object in the XML tag. So this is the class name. AUDIENCE: OK, thanks. PAUL LESIAK: Does that help? AUDIENCE: Yeah. PAUL LESIAK: OK. All right.
Authentication, this is sort of boring. So I'm not going to spend a lot of time. Pretty much you post the AAA login object. You get back a cookie that contains a token. And also within the payload, you'll get a token value there. So for subsequent requests, just set that cookie. And then you can continue without needing to authenticate every time.
This is just a bunch of different query types. Actually, the one interesting one is you can do wild card expressions. So you can say show me every single tenant that has coke in their name or in the description for the tenant name.
So we went through the tree based structure. We've gone through what those REST requests look like. Now, let's start to make life a little bit easier on ourselves. Let's say you don't want to have to go and manually type all of those query strings. Well, luckily there's this tool called Visore that's on APIC. And if you're familiar with UCS, you've probably worked with it, too. It's an view object viewer. Apparently, Visore in Italian means viewer, or to view, or something like that. That's what one of the developers told me. I don't know. It probably means something else. But in any case, you can access it by just hitting /visore.html on your APIC. And then you go in there and start querying for individual objects. So I could say find me all of the-- bless you-- all of the tenants. Find me top system. Fine me all the leaf nodes, all this stuff. And you'll get that information back. To make life a little bit easier, you also have a couple of links that are not shown on the screen here. But there's a couple links that allow you to show the query URI of the last query you did. And also another one that shows you what the payload was of the last response. So that way, you can point and click your way through the object model to find that information, but then get the actual REST queries that were generated to do that.
POSTMAN. So Cesar was just asking about POSTMAN. This is a pretty cool tool for just being able to go in and play around the REST queries. You can pop in a URL, set a method type, put in your payload. And then POSTMAN will actually go and configure that. And the really nice thing about POSTMAN is that you can create collections in it, and then share it with other people. So if Prem does something really cool, and he wants to share it with everybody else in the room, he can export it in a POSTMAN collection, and then send it to you guys. You guys can import it, and then run it on your own APICs without having to send tons and tons of XML of JSON. It's a pretty neat feature. And then this is really just for reference, how you can do various things to start off with. All right.
Any questions before I go into the SDK? OK, good. Does anybody have any ideas as to what the BR in VZBRCP stands for? AUDIENCE: Broadcast? PAUL LESIAK: Broadcast? No. Because think about it, it's a contract. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Did you say binary? You said binary? You said binary? You win. AUDIENCE: I get a sticker. PAUL LESIAK: Yeah, you do. So wait, who's getting a sticker now? You're getting a-- No. You got to answer one of the questions first. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yes, you can. You can cash them in. Not on camera. Because I think he already doesn't like me.
AUDIENCE: He doesn't like [INAUDIBLE]. PAUL LESIAK: I know, I know. AUDIENCE: He doesn't like humans. PAUL LESIAK: But he is human, though. OK. So Cobra is the SDK written in Python for ACI. So this is going to be open sourced imminently. Right? Three weeks ago I had a meeting with Prem. He said, yes. We'll open source this. We just need to wait to make sure Arista or competitors don't go and like reverse engineer it. Today, I was speaking to some guys in marketing. They said, yes. We're going to be open sourcing this other aspect of it. That means that Cobra can be open sourced. So intimately, it'll be open sourced. That means that customers out there that are like begging and pleading with us-- open source it, open source it, we want to use it-- they'll be able to do that. So that's good. All of the stuff that I just went over with the REST API, you can do all of that in Cobra. And I think, personally, it's a lot easier. Because you're not sitting there and writing pages and pages of XML or JSON. Instead, you write code, which is very nice. Because it generates the JSON or the XML for you. It also has this really nice side effect, advantage, that the objects in Cobra are a 1 to 1 representation of what's in the object model. What that means is that you have built-in verification of what you're doing. So if I go in there and I screw up my code and I tried to attach an EPG to an interface-- well, no. I guess that's sort of-- AUDIENCE: To a leaf. PAUL LESIAK: To a leaf, yeah. Thank you. That's a good-- two stickers. If I go and I try to attach an EPG to a leaf, what does that mean? It's not going to do anything. Well, Cobra will catch that and tell you, hey, you're being stupid. Fix your code. It also does consistency checks on all the information. So if for some reason you get bad information back, it's going to inform you that, hey, this information that was provided back from APIC was malformed. And it's packaged as a Python egg. It'll be on [INAUDIBLE] soon. AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Yes. I need to actually start hurrying up here. What's your name again? AUDIENCE: Dorn. PAUL LESIAK: Dorn? What? AUDIENCE: Who are you pointing to? PAUL LESIAK: Yeah, yeah.
AUDIENCE: [INAUDIBLE]. PAUL LESIAK: Arya will be consistent. The code that's generated should be consistent within a major release. Between major releases, they might need to make model changes. So if they find that they screwed up with the naming of something or god knows what, it could change. All right. So just the basic login operation, I know it's painful to read through source code. So I'll leave this as a point of reference for you guys, unless anybody has a particular question about this. Any questions? OK I'm going to pass through this one. Please refer to it for reference. The slides animate, and they're really pretty.
For doing queries on objects, if you want to do a lookup on an object, you do lookupByDN. If you want to do a lookup by class, you do lookupByClass, pretty intuitive.
AUDIENCE: Paul, are certificate rates authentication, are they supported yet? PAUL LESIAK: Yes, they are now. Me and Mike Timm spent a lot of time-- mostly Mike Timm spent a lot of time reimplementing that to make it fully functional. So that is working now. So object creation, one way that you could go about creating objects is to look up the point in the tree where you want to create it, and then just start creating the objects underneath it. So this one over here is just registering a couple of nodes on a simulator. We can use Visore to find that class ID.
And then we can instead do a lookup by class, which is probably the better way to do things. Because doing a lookup by DN means that you expect that the object will be there. Whereas, it may not always be there. So you want to be able to handle those types of failure conditions. And of course, we removed the hard coding of that DN string. And then we can add the MO to a configure request, and then post it.
All right. This stuff is-- and does anybody in the room want me to sit here and read through lines of code? No. No. Do you really? I'll give you a sticker if you do. But everybody else will take your life though.
OK. So again, these are all examples for your reference. If you want to see how to go through and create a three tiered application or whatnot, I tried to make it fit into a single PowerPoint slide for a lot of these relationships-- AUDIENCE: Paul, can you go back [INAUDIBLE]? PAUL LESIAK: Yes. This one? AUDIENCE: I don't want you to read it. PAUL LESIAK: Oh, OK. I hope you don't want me to read it. OK.