A "pseudo dynamic" client for the VMware NSX for vSphere API that uses a RAML file describing the API as an Input to generate the API calls
Project description
nsxramlclient
This ‘somewhat dynamic client’ gets its API structure information (e.g. URLs, parameters, schema, etc.) from a RAML file. It is only tested and used with the RAML file specific to VMware NSX Manager (NSX for vSphere).
The latest version of the NSXv RAML file can be found at http://github.com/yfauser/nsxraml
How to install nsxramlclient
The following install instructions will focus on Ubuntu 14.04 LTS, but installations on other Linux distributions or on MAC should be relatively similar.
Check whether pip is installed
pip --version
If pip is not installed, install it with apt-get
sudo apt-get update
sudo apt-get -y install python-pip
Now you can install the nsx raml client using pip
sudo pip install nsxramlclient
If the installation fails because of missing dependencies of lxml, you will see the following message
ERROR: /bin/sh: 1: xslt-config: not found ** make sure the development packages of libxml2 and libxslt are installed **
In this case install the following packages through apt-get, and then repeat the above pip installation of the nsx raml client:
sudo apt-get install libxml2-dev libxslt-dev python-dev zlib1g-dev
How to use nsxramlclient
Create a session object
The first thing you do is to create a session object to work with. This session object will then expose the create, read, update and delete (CRUD) as well as some helper methods to you.
from nsxramlclient.client import NsxClient
nsxraml_file = '/raml/nsxvraml/nsxvapiv614.raml'
nsxmanager = 'nsxmanager.invalid.org'
nsx_username = 'admin'
nsx_password = 'vmware'
client_session = NsxClient(nsxraml_file, nsxmanager, nsx_username,
nsx_password, debug=False)
The NsxClient Class has the following initialization parameters:
"""
:param raml_file:
This mandatory parameter is the RAML File used as the basis of all URL
compositions and to extract the body schema and convert them into python dictionaries
:param nsxmanager:
This mandatory parameter is either the hostname or IP Address of the NSX Manager
:param nsx_username:
This mandatory parameter is the Username on NSX Manager used to do API Calls
:param nsx_password:
This mandatory parameter is the Password of the User used to do API Calls
:param debug: Optional:
If set to True, the client will print extensive HTTP session information to stdout.
Default: False
:param verify: Optional:
If set to True, the client will strictly verify the certificate passed by NSX Manager.
Default: False
:param suppress_warnings: Optional:
If set to True, the client will print out a warning if NSX Manager uses a self signed certificate.
Default: True
:return: Returns a NsxClient Session Object
"""
After you initialized a session object you have access to the following methods: - create: Sends a HTTP POST to NSX Manager. More details will follow later in this readme
read: Sends a HTTP GET to NSX Manager
update: Sends a HTTP PUT to NSX Manager
delete: Sends a HTTP DELETE to NSX Manager
view_response: Each of the above methods returns a Python OrderedDictionary with the HTTP Status code, location header, NSX Object Id, eTag Header and Body. This methods outputs the OrderedDict out in a human readable text to stdout
extract_resource_body_schema: This method will retrieve the body schema out of the RAML File (if the method has a body schema like most create methods), and will return a template python dictionary that can be used to construct your call
view_resource_body_schema: This method retrieves the body schema out of the RAML file and outputs it to stdout as a pretty printed XML document
view_body_dict: This method takes a body dictionary (any python dictionary), and outputs it in a more human readable way to stdout
view_resource_display_names: This method outputs all displayNames and description of all resources in the RAML File with their associated URI & Query parameters, additional Headers and what methods (CRUD) are supported
Use the create, read, update and delete methods
In [1]: client_session.read('vCenterStatus')
Out[2]: OrderedDict([('status', 200), ('body', {'vcConfigStatus': {'connected': 'true', 'lastInventorySyncTime': '1440444721014'}}), ('location', None), ('objectId', None), ('Etag', None)])
As you can see the create, read, update and delete methods return an Python OrderedDict with the following key/value pairs: - status: The HTTP status code returned as an integer - body: The response body returned as a dict. If no body was returned this will be None - location: If a location header is returned, this value will be the returned location URL as a string, else it will be None - objectId: If a location header is returned, the value of objectId will be the last part of the location url as a string, else it will be None - Etag: If a Etag header is returned, the value of Etag will be the content of the Etag header returned, else it will be None
To output the response in a more human readable way when working in an interactive session, you can use the view_response method:
In [3]: response = client_session.read('vCenterStatus')
In [4]: client_session.view_response(response)
HTTP status code:
200
HTTP Body Content:
{'vcConfigStatus': {'connected': 'true',
'lastInventorySyncTime': '1440445281484'}}
If a method needs a URI parameter to work, the NSX RAML Client will compose the URL based on the base URL, parent and child method URL and the supplied URI parameter. To supply a URI parameter, add a URI parameter dict to your call. You can supply multiple URI parameters in the call when needed.
In [5]: response = client_session.read('vdnSegmentPool',
uri_parameters={'segmentPoolId': '2'})
In [6]: client_session.view_response(response)
HTTP status code:
200
HTTP Body Content:
{'segmentRange': {'begin': '5000',
'end': '10000',
'id': '2',
'name': 'legacy'}}
If a method needs one or more query parameters to work, or you want to supply optional query parameters, the NSX RAML Client will add the query parameter for you. To use this pass a query parameter dict to the call:
In [7]: response = client_session.read('nwfabricStatus',
query_parameters_dict={'resource':
'domain-c1632'})
In [8]: client_session.view_response(response)
HTTP status code:
200
.... truncated for brevity ....
Of course you can use URI and query parameters concurrently in any call you make, and add as many as the resource specifies.
Finally if a resource requires a body to be supplied with data, you can compose the body in the following way:
First you can check what the body of a call needs to look like by retrieving it out of the RAML file, and displaying it to stdout using view_resource_body_schema:
In [9]: client_session.view_resource_body_schema('logicalSwitches', 'create')
<virtualWireCreateSpec>
<name>mandatory</name>
<description/>
<tenantId>mandatory</tenantId>
<controlPlaneMode>mandatory</controlPlaneMode>
</virtualWireCreateSpec>
Also you can create a template python dictionary using extract_resource_body_schema, and if you want you can also output its structure in a human readable way to stdout:
In [10]: new_ls = client_session.extract_resource_body_schema('logicalSwitches',
'create')
In [11]: client_session.view_body_dict(new_ls)
{'virtualWireCreateSpec': {'controlPlaneMode': 'mandatory',
'description': None,
'name': 'mandatory',
'tenantId': 'mandatory'}}
You can now change some values in the dictionary with the data you want to send to the API:
In [12]: new_ls['virtualWireCreateSpec']['controlPlaneMode'] = 'UNICAST_MODE'
In [13]: new_ls['virtualWireCreateSpec']['name'] = 'TestLogicalSwitch1'
In [14]: new_ls['virtualWireCreateSpec']['tenantId'] = 'Tenant1'
In [15]: client_session.view_body_dict(new_ls)
{'virtualWireCreateSpec': {'controlPlaneMode': 'UNICAST_MODE',
'description': None,
'name': 'TestLogicalSwitch1',
'tenantId': 'Tenant1'}}
And finally you send the call to the NSX Manager API by supplying the body dictionary in the call:
In [16]: new_ls_response = client_session.create('logicalSwitches',
uri_parameters={'scopeId':
'vdnscope-1'},
request_body_dict=new_ls)
In [17]: client_session.view_response(new_ls_response)
HTTP status code:
201
HTTP location header:
/api/2.0/vdn/virtualwires/virtualwire-1305
NSX Object Id:
virtualwire-1305
HTTP Body Content:
'virtualwire-1305'
Note on Etag header and additional headers (e.g. If-match)
Some resources in NSX Manager will need an additional header supplied, namely the If-match header. To compose the If-match header, one retrieves the content of the Etag and returns it in the If-match header. This is e.g used in the distributed firewall configuration to deal with conflicts when two users concurrently try to edit the rule sets.
Here’s an example on how to retrieve a dfw rule, edit it, and update it on NSX Manager:
rule_read_response = client_session.read('dfwL3Rule',
uri_parameters={'sectionId': section_id,
'ruleId': new_rule_id})
updated_rule = l3_dfw_rule_read_response['body']
etag_value = l3_dfw_rule_read_response['Etag']
updated_rule['rule']['name'] = 'UpdatedByRAMLClient'
update_response = client_session.update('dfwL3Rule',
uri_parameters={'sectionId': section_id,
'ruleId': rule_id},
additional_headers={'If-match': etag_value},
request_body_dict=updated_rule)
As you can see the If-match header is supplied by the additional_headers dictionary.
Note on repeating key/value pairs and resulting python lists containing dicts
In some cases NSX Manager uses lists of parameters with repeating keys. Here’s an example:
In [21]: client_session.view_resource_body_schema('dfwL3Section', 'create')
<section name="Test">
<rule disabled="false" logged="true">
<name/>
<action>ALLOW</action>
<appliedToList>
<appliedTo>
<name/>
<value/>
<type/>
<isValid/>
</appliedTo>
</appliedToList>
<sources excluded="false">
<source>
<name/>
<value/>
<type/>
<isValid/>
</source>
<source>
<name/>
<value/>
<type/>
<isValid/>
</source>
</sources>
<destinations excluded="false">
<destination>
<name/>
<value/>
<type/>
<isValid/>
</destination>
<destination>
<name/>
<value/>
<type/>
<isValid/>
</destination>
</destinations>
<services>
<service>
<destinationPort/>
<protocol/>
<subProtocol/>
</service>
</services>
</rule>
<rule disabled="false" logged="true">
<name/>
<action>DENY</action>
</rule>
</section>
As you can see, there are multiple destination keys under destinations. To be able to work with python dictionaries, nsxramlclient will convert those list of equally named parameter ‘groups’ to a python list containing dictionaries. Here’s the resulting python dictionary for this type of resource body schema:
In [22]: dfw_l3_sec = client_session.extract_resource_body_schema('dfwL3Section',
'create')
In [31]: client_session.view_body_dict(dfw_l3_sec)
{'section': {'@name': 'Test',
'rule': [{'@disabled': 'false',
'@logged': 'true',
'action': 'ALLOW',
'appliedToList': {'appliedTo': {'isValid': None,
'name': None,
'type': None,
'value': None}},
'destinations': {'@excluded': 'false',
'destination': [{'isValid': None,
'name': None,
'type': None,
'value': None},
{'isValid': None,
'name': None,
'type': None,
'value': None}]},
'name': None,
'services': {'service': {'destinationPort': None,
'protocol': None,
'subProtocol': None}},
'sources': {'@excluded': 'false',
'source': [{'isValid': None,
'name': None,
'type': None,
'value': None},
{'isValid': None,
'name': None,
'type': None,
'value': None}]}},
{'@disabled': 'false',
'@logged': 'true',
'action': 'DENY',
'name': None}]}}
Note the rule key, its value is a python List containing multiple rule objects that themselves are python dictionaries. Same holds true for the destinationsand sources keys.
License
The MIT License (MIT)
Copyright (c) 2015 nsxramlclient
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
How to contribute
Any contributions are welcome, bug reports, additional tests, enhancements, etc. Also we welcome your feedback if you find that anything is missing that would make nsxramlclient better
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file nsxramlclient-1.0.0rc1.tar.gz
.
File metadata
- Download URL: nsxramlclient-1.0.0rc1.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ca615fb18a505b5eb555caf97be6f94f4f26b8973c7da16fa3af22d4cc743f5a |
|
MD5 | e2ec463652048001bd81cc3a8b616b2b |
|
BLAKE2b-256 | e7eced55819149a12194d7db10b380b26f42c165d911daefb13b81b7b8a4a47e |