Preparing your Mac for VMware NSX-v Python Development

PyNSXv is a high level python based library that exposes ready to use work-flows and a CLI tool that can be used to control VMware NSX for vSphere.

PyNSXv can be used in two different ways, as a library by importing the files in the /library subdirectory into your code, or as a CLI tool by executing pynsxv, from the command line after installation.

To install PyNSXv you’ll need to install or update MacOS Xcode, Python, Homebrew, plus some of the XML formating dependencies needed by PyNSXv and the underlying nsxramlclient.

1. Install Xcode and Python
xcode-select –install
curl https://bootstrap.pypa.io/get-pip.py > get-pip.py
sudo python get-pip.py

MacBook-Pro:~ erik$ xcode-select —install
xcode-select: note: install requested for command line developer tools
MacBook-Pro:~ erik$ curl https://bootstrap.pypa.io/get-pip.py > get-pip.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1622k  100 1622k    0     0  3468k      0 --:--:-- --:--:-- --:--:-- 3467k
MacBook-Pro:~ erik$ sudo python get-pip.py
Password:
Collecting pip
  Downloading https://files.pythonhosted.org/packages/c2/d7/90f34cb0d83a6c5631cf71dfe64cc1054598c843a92b400e55675cc2ac37/pip-18.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 4.2MB/s 
Collecting wheel
  Downloading https://files.pythonhosted.org/packages/fc/e9/05316a1eec70c2bfc1c823a259546475bd7636ba6d27ec80575da523bc34/wheel-0.32.1-py2.py3-none-any.whl
Installing collected packages: pip, wheel
Successfully installed pip-18.1 wheel-0.32.1

2. Install Homebrew using Ruby
/usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

MacBook-Pro:~ erik$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following existing directories will be made group writable:
/usr/local/bin
/usr/local/share
/usr/local/share/man
/usr/local/share/man/man1
==> The following existing directories will have their owner set to erik:
/usr/local/bin
/usr/local/share
/usr/local/share/man
/usr/local/share/man/man1
==> The following existing directories will have their group set to admin:
/usr/local/bin
/usr/local/share
/usr/local/share/man
/usr/local/share/man/man1
==> The following new directories will be created:
/usr/local/etc
/usr/local/include
/usr/local/lib
/usr/local/sbin
/usr/local/var
/usr/local/opt
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var/homebrew
/usr/local/var/homebrew/linked
/usr/local/Cellar
/usr/local/Caskroom
/usr/local/Homebrew
/usr/local/Frameworks
Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/chmod u+rwx /usr/local/bin /usr/local/share /usr/local/share/man /usr/local/share/man/man1
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/bin /usr/local/share /usr/local/share/man /usr/local/share/man/man1
==> /usr/bin/sudo /usr/sbin/chown erik /usr/local/bin /usr/local/share /usr/local/share/man /usr/local/share/man/man1
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/bin /usr/local/share /usr/local/share/man /usr/local/share/man/man1
==> /usr/bin/sudo /bin/mkdir -p /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
==> /usr/bin/sudo /usr/sbin/chown erik /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /bin/mkdir -p /Users/erik/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Users/erik/Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown erik /Users/erik/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/mkdir -p /Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown erik /Library/Caches/Homebrew
==> Downloading and installing Homebrew...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 112581 (delta 21), reused 30 (delta 15), pack-reused 112539
Receiving objects: 100% (112581/112581), 25.80 MiB | 7.09 MiB/s, done.
Resolving deltas: 100% (82358/82358), done.
From https://github.com/Homebrew/brew
 * [new branch]          master     -> origin/master
 * [new tag]             0.1        -> 0.1
 * [new tag]             0.2        -> 0.2
 * [new tag]             0.3        -> 0.3
 * [new tag]             0.4        -> 0.4
 * [new tag]             0.5        -> 0.5
 * [new tag]             0.6        -> 0.6
 * [new tag]             0.7        -> 0.7
 * [new tag]             0.7.1      -> 0.7.1
 * [new tag]             0.8        -> 0.8
 * [new tag]             0.8.1      -> 0.8.1
 * [new tag]             0.9        -> 0.9
 * [new tag]             0.9.1      -> 0.9.1
 * [new tag]             0.9.2      -> 0.9.2
 * [new tag]             0.9.3      -> 0.9.3
 * [new tag]             0.9.4      -> 0.9.4
 * [new tag]             0.9.5      -> 0.9.5
 * [new tag]             0.9.8      -> 0.9.8
 * [new tag]             0.9.9      -> 0.9.9
 * [new tag]             1.0.0      -> 1.0.0
 * [new tag]             1.0.1      -> 1.0.1
 * [new tag]             1.0.2      -> 1.0.2
 * [new tag]             1.0.3      -> 1.0.3
 * [new tag]             1.0.4      -> 1.0.4
 * [new tag]             1.0.5      -> 1.0.5
 * [new tag]             1.0.6      -> 1.0.6
 * [new tag]             1.0.7      -> 1.0.7
 * [new tag]             1.0.8      -> 1.0.8
 * [new tag]             1.0.9      -> 1.0.9
 * [new tag]             1.1.0      -> 1.1.0
 * [new tag]             1.1.1      -> 1.1.1
 * [new tag]             1.1.10     -> 1.1.10
 * [new tag]             1.1.11     -> 1.1.11
 * [new tag]             1.1.12     -> 1.1.12
 * [new tag]             1.1.13     -> 1.1.13
 * [new tag]             1.1.2      -> 1.1.2
 * [new tag]             1.1.3      -> 1.1.3
 * [new tag]             1.1.4      -> 1.1.4
 * [new tag]             1.1.5      -> 1.1.5
 * [new tag]             1.1.6      -> 1.1.6
 * [new tag]             1.1.7      -> 1.1.7
 * [new tag]             1.1.8      -> 1.1.8
 * [new tag]             1.1.9      -> 1.1.9
 * [new tag]             1.2.0      -> 1.2.0
 * [new tag]             1.2.1      -> 1.2.1
 * [new tag]             1.2.2      -> 1.2.2
 * [new tag]             1.2.3      -> 1.2.3
 * [new tag]             1.2.4      -> 1.2.4
 * [new tag]             1.2.5      -> 1.2.5
 * [new tag]             1.2.6      -> 1.2.6
 * [new tag]             1.3.0      -> 1.3.0
 * [new tag]             1.3.1      -> 1.3.1
 * [new tag]             1.3.2      -> 1.3.2
 * [new tag]             1.3.3      -> 1.3.3
 * [new tag]             1.3.4      -> 1.3.4
 * [new tag]             1.3.5      -> 1.3.5
 * [new tag]             1.3.6      -> 1.3.6
 * [new tag]             1.3.7      -> 1.3.7
 * [new tag]             1.3.8      -> 1.3.8
 * [new tag]             1.3.9      -> 1.3.9
 * [new tag]             1.4.0      -> 1.4.0
 * [new tag]             1.4.1      -> 1.4.1
 * [new tag]             1.4.2      -> 1.4.2
 * [new tag]             1.4.3      -> 1.4.3
 * [new tag]             1.5.0      -> 1.5.0
 * [new tag]             1.5.1      -> 1.5.1
 * [new tag]             1.5.10     -> 1.5.10
 * [new tag]             1.5.11     -> 1.5.11
 * [new tag]             1.5.12     -> 1.5.12
 * [new tag]             1.5.13     -> 1.5.13
 * [new tag]             1.5.14     -> 1.5.14
 * [new tag]             1.5.2      -> 1.5.2
 * [new tag]             1.5.3      -> 1.5.3
 * [new tag]             1.5.4      -> 1.5.4
 * [new tag]             1.5.5      -> 1.5.5
 * [new tag]             1.5.6      -> 1.5.6
 * [new tag]             1.5.7      -> 1.5.7
 * [new tag]             1.5.8      -> 1.5.8
 * [new tag]             1.5.9      -> 1.5.9
 * [new tag]             1.6.0      -> 1.6.0
 * [new tag]             1.6.1      -> 1.6.1
 * [new tag]             1.6.10     -> 1.6.10
 * [new tag]             1.6.11     -> 1.6.11
 * [new tag]             1.6.12     -> 1.6.12
 * [new tag]             1.6.13     -> 1.6.13
 * [new tag]             1.6.14     -> 1.6.14
 * [new tag]             1.6.15     -> 1.6.15
 * [new tag]             1.6.16     -> 1.6.16
 * [new tag]             1.6.17     -> 1.6.17
 * [new tag]             1.6.2      -> 1.6.2
 * [new tag]             1.6.3      -> 1.6.3
 * [new tag]             1.6.4      -> 1.6.4
 * [new tag]             1.6.5      -> 1.6.5
 * [new tag]             1.6.6      -> 1.6.6
 * [new tag]             1.6.7      -> 1.6.7
 * [new tag]             1.6.8      -> 1.6.8
 * [new tag]             1.6.9      -> 1.6.9
 * [new tag]             1.7.0      -> 1.7.0
 * [new tag]             1.7.1      -> 1.7.1
 * [new tag]             1.7.2      -> 1.7.2
 * [new tag]             1.7.3      -> 1.7.3
 * [new tag]             1.7.4      -> 1.7.4
 * [new tag]             1.7.5      -> 1.7.5
 * [new tag]             1.7.6      -> 1.7.6
 * [new tag]             1.7.7      -> 1.7.7
HEAD is now at de9cb6920 Merge pull request #5123 from reitermarkus/test-locks
==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations
==> Tapping homebrew/core
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core'...
remote: Enumerating objects: 4851, done.
remote: Counting objects: 100% (4851/4851), done.
remote: Compressing objects: 100% (4650/4650), done.
remote: Total 4851 (delta 55), reused 321 (delta 11), pack-reused 0
Receiving objects: 100% (4851/4851), 4.05 MiB | 2.65 MiB/s, done.
Resolving deltas: 100% (55/55), done.
Tapped 2 commands and 4637 formulae (4,893 files, 12.6MB).
==> Migrating /Library/Caches/Homebrew to /Users/erik/Library/Caches/Homebrew...
==> Deleting /Library/Caches/Homebrew...
Already up-to-date.
==> Installation successful!
==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics.html
==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations

3. Install the XML formating dependencies needed by PyNSXv and the nsxramlclient
brew install libxml2
brew install libxslt
brew link libxml2 –force
brew link libxslt –force

MacBook-Pro:~ erik$ brew install libxml2
==> Installing dependencies for libxml2: gdbm, openssl, readline, sqlite and python@2
==> Installing libxml2 dependency: gdbm
==> Downloading https://homebrew.bintray.com/bottles/gdbm-1.18.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring gdbm-1.18.high_sierra.bottle.tar.gz
🍺  /usr/local/Cellar/gdbm/1.18: 20 files, 584.4KB
==> Installing libxml2 dependency: openssl
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2p.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring openssl-1.0.2p.high_sierra.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
  /usr/local/etc/openssl/certs
and run
  /usr/local/opt/openssl/bin/c_rehash
openssl is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.
If you need to have openssl first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl/include"
==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2p: 1,793 files, 12.3MB
==> Installing libxml2 dependency: readline
==> Downloading https://homebrew.bintray.com/bottles/readline-7.0.5.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring readline-7.0.5.high_sierra.bottle.tar.gz
==> Caveats
readline is keg-only, which means it was not symlinked into /usr/local,
because macOS provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.
For compilers to find readline you may need to set:
  export LDFLAGS="-L/usr/local/opt/readline/lib"
  export CPPFLAGS="-I/usr/local/opt/readline/include"
==> Summary
🍺  /usr/local/Cellar/readline/7.0.5: 46 files, 1.5MB
==> Installing libxml2 dependency: sqlite
==> Downloading https://homebrew.bintray.com/bottles/sqlite-3.25.2.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring sqlite-3.25.2.high_sierra.bottle.tar.gz
==> Caveats
sqlite is keg-only, which means it was not symlinked into /usr/local,
because macOS provides an older sqlite3.
If you need to have sqlite first in your PATH run:
  echo 'export PATH="/usr/local/opt/sqlite/bin:$PATH"' >> ~/.bash_profile
For compilers to find sqlite you may need to set:
  export LDFLAGS="-L/usr/local/opt/sqlite/lib"
  export CPPFLAGS="-I/usr/local/opt/sqlite/include"
==> Summary
🍺  /usr/local/Cellar/sqlite/3.25.2: 11 files, 3.7MB
==> Installing libxml2 dependency: python@2
==> Downloading https://homebrew.bintray.com/bottles/python@2-2.7.15_1.high_sierra.bottle.6.tar.gz
######################################################################## 100.0%
==> Pouring python@2-2.7.15_1.high_sierra.bottle.6.tar.gz
==> /usr/local/Cellar/python@2/2.7.15_1/bin/python -s setup.py --no-user-cfg install --force --verbose --single-version-externally
==> /usr/local/Cellar/python@2/2.7.15_1/bin/python -s setup.py --no-user-cfg install --force --verbose --single-version-externally
==> /usr/local/Cellar/python@2/2.7.15_1/bin/python -s setup.py --no-user-cfg install --force --verbose --single-version-externally
==> Caveats
Pip and setuptools have been installed. To update them
  pip install --upgrade pip setuptools
You can install Python packages with
  pip install <package>
They will install into the site-package directory
  /usr/local/lib/python2.7/site-packages
See: https://docs.brew.sh/Homebrew-and-Python
==> Summary
🍺  /usr/local/Cellar/python@2/2.7.15_1: 4,665 files, 82.6MB
==> Installing libxml2
==> Downloading https://homebrew.bintray.com/bottles/libxml2-2.9.7.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libxml2-2.9.7.high_sierra.bottle.tar.gz
==> Caveats
libxml2 is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have libxml2 first in your PATH run:
  echo 'export PATH="/usr/local/opt/libxml2/bin:$PATH"' >> ~/.bash_profile
For compilers to find libxml2 you may need to set:
  export LDFLAGS="-L/usr/local/opt/libxml2/lib"
  export CPPFLAGS="-I/usr/local/opt/libxml2/include"
==> Summary
🍺  /usr/local/Cellar/libxml2/2.9.7: 281 files, 10.4MB
==> Caveats
==> openssl
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
  /usr/local/etc/openssl/certs
and run
  /usr/local/opt/openssl/bin/c_rehash
openssl is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.
If you need to have openssl first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl/include"
==> readline
readline is keg-only, which means it was not symlinked into /usr/local,
because macOS provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.
For compilers to find readline you may need to set:
  export LDFLAGS="-L/usr/local/opt/readline/lib"
  export CPPFLAGS="-I/usr/local/opt/readline/include"
==> sqlite
sqlite is keg-only, which means it was not symlinked into /usr/local,
because macOS provides an older sqlite3.
If you need to have sqlite first in your PATH run:
  echo 'export PATH="/usr/local/opt/sqlite/bin:$PATH"' >> ~/.bash_profile
For compilers to find sqlite you may need to set:
  export LDFLAGS="-L/usr/local/opt/sqlite/lib"
  export CPPFLAGS="-I/usr/local/opt/sqlite/include"
==> python@2
Pip and setuptools have been installed. To update them
  pip install --upgrade pip setuptools
You can install Python packages with
  pip install <package>
They will install into the site-package directory
  /usr/local/lib/python2.7/site-packages
See: https://docs.brew.sh/Homebrew-and-Python
==> libxml2
libxml2 is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have libxml2 first in your PATH run:
  echo 'export PATH="/usr/local/opt/libxml2/bin:$PATH"' >> ~/.bash_profile
For compilers to find libxml2 you may need to set:
  export LDFLAGS="-L/usr/local/opt/libxml2/lib"
  export CPPFLAGS="-I/usr/local/opt/libxml2/include"
MacBook-Pro:~ erik$ brew install libxslt
==> Downloading https://homebrew.bintray.com/bottles/libxslt-1.1.32.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libxslt-1.1.32.high_sierra.bottle.tar.gz
==> Caveats
To allow the nokogiri gem to link against this libxslt run:
  gem install nokogiri -- --with-xslt-dir=/usr/local/opt/libxslt
libxslt is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have libxslt first in your PATH run:
  echo 'export PATH="/usr/local/opt/libxslt/bin:$PATH"' >> ~/.bash_profile
For compilers to find libxslt you may need to set:
  export LDFLAGS="-L/usr/local/opt/libxslt/lib"
  export CPPFLAGS="-I/usr/local/opt/libxslt/include"
==> Summary
🍺  /usr/local/Cellar/libxslt/1.1.32: 148 files, 3MB
MacBook-Pro:~ erik$ brew link libxml2 --force
Linking /usr/local/Cellar/libxml2/2.9.7... 21 symlinks created
If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/libxml2/bin:$PATH"' >> ~/.bash_profile
MacBook-Pro:~ erik$ brew link libxslt --force
Linking /usr/local/Cellar/libxslt/1.1.32... 22 symlinks created
If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/libxslt/bin:$PATH"' >> ~/.bash_profile
MacBook-Pro:~ erik$ echo 'export PATH="/usr/local/opt/libxslt/bin:$PATH"' >> ~/.bash_profile

4. Install PyNSXv
sudo pip install pynsxv

MacBook-Pro:~ erik$ sudo pip install pynsxv
Password:
The directory '/Users/erik/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/erik/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting pynsxv
  Downloading https://files.pythonhosted.org/packages/9e/a4/231aed804e77bbd7825f74a129879b600d2316926e1ecc31fa295b673ab4/PyNSXv-0.4.1.tar.gz (137kB)
    100% |████████████████████████████████| 143kB 2.3MB/s 
Collecting nsxramlclient>=2.0.1 (from pynsxv)
  Downloading https://files.pythonhosted.org/packages/b3/da/bda98b9ce1f8d52a34708c75bfdd1dd8076e6c59a020d9173e682e9196af/nsxramlclient-2.0.7.tar.gz
Collecting pyvmomi (from pynsxv)
  Downloading https://files.pythonhosted.org/packages/b2/0c/6d6772be8df97d0965a1531612035f883a16dae5a892c835687507f683ac/pyvmomi-6.7.0.2018.9.tar.gz (262kB)
    100% |████████████████████████████████| 266kB 2.2MB/s 
Collecting tabulate (from pynsxv)
  Downloading https://files.pythonhosted.org/packages/12/c2/11d6845db5edf1295bc08b2f488cf5937806586afe42936c3f34c097ebdc/tabulate-0.8.2.tar.gz (45kB)
    100% |████████████████████████████████| 51kB 8.3MB/s 
Collecting pyopenssl (from nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/96/af/9d29e6bd40823061aea2e0574ccb2fcf72bfd6130ce53d32773ec375458c/pyOpenSSL-18.0.0-py2.py3-none-any.whl (53kB)
    100% |████████████████████████████████| 61kB 10.8MB/s 
Collecting pyraml-parser>=0.1.3 (from nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/9b/82/58f8e545845fa56cd05c6a28f604151252276d45d0ab6df3ba5527e61cfe/pyraml-parser-0.1.7.tar.gz
Collecting lxml&lt;=3.6.0 (from nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/11/1b/fe6904151b37a0d6da6e60c13583945f8ce3eae8ebd0ec763ce546358947/lxml-3.6.0.tar.gz (3.7MB)
    100% |████████████████████████████████| 3.7MB 2.3MB/s 
Collecting requests>=2.7.0 (from nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/65/47/7e02164a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda/requests-2.19.1-py2.py3-none-any.whl (91kB)
    100% |████████████████████████████████| 92kB 2.4MB/s 
Collecting six>=1.7.3 (from pyvmomi->pynsxv)
  Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Collecting cryptography>=2.2.1 (from pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/5d/b1/9863611b121ee524135bc0068533e6d238cc837337170e722224fe940e2d/cryptography-2.3.1-cp27-cp27m-macosx_10_6_intel.whl (1.5MB)
    100% |████████████████████████████████| 1.5MB 2.9MB/s 
Requirement already satisfied: setuptools in /usr/local/lib/python2.7/site-packages (from pyraml-parser>=0.1.3->nsxramlclient>=2.0.1->pynsxv) (40.4.3)
Collecting PyYAML>=3.10 (from pyraml-parser>=0.1.3->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz (270kB)
    100% |████████████████████████████████| 276kB 3.5MB/s 
Collecting certifi>=2017.4.17 (from requests>=2.7.0->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/56/9d/1d02dd80bc4cd955f98980f28c5ee2200e1209292d5f9e9cc8d030d18655/certifi-2018.10.15-py2.py3-none-any.whl (146kB)
    100% |████████████████████████████████| 153kB 3.6MB/s 
Collecting urllib3&lt;1.24,>=1.21.1 (from requests>=2.7.0->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB)
    100% |████████████████████████████████| 143kB 3.8MB/s 
Collecting chardet&lt;3.1.0,>=3.0.2 (from requests>=2.7.0->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
    100% |████████████████████████████████| 143kB 3.7MB/s 
Collecting idna&lt;2.8,>=2.5 (from requests>=2.7.0->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
    100% |████████████████████████████████| 61kB 10.5MB/s 
Collecting cffi!=1.11.3,>=1.7 (from cryptography>=2.2.1->pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/7e/4a/b647e46faaa2dcfb16069b6aad2d8509982fd63710a325b8ad7db80f18be/cffi-1.11.5-cp27-cp27m-macosx_10_6_intel.whl (238kB)
    100% |████████████████████████████████| 245kB 4.2MB/s 
Collecting enum34; python_version &lt; "3" (from cryptography>=2.2.1->pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/c5/db/e56e6b4bbac7c4a06de1c50de6fe1ef3810018ae11732a50f15f62c7d050/enum34-1.1.6-py2-none-any.whl
Collecting asn1crypto>=0.21.0 (from cryptography>=2.2.1->pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB)
    100% |████████████████████████████████| 102kB 4.4MB/s 
Collecting ipaddress; python_version &lt; "3" (from cryptography>=2.2.1->pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/fc/d0/7fc3a811e011d4b388be48a0e381db8d990042df54aa4ef4599a31d39853/ipaddress-1.0.22-py2.py3-none-any.whl
Collecting pycparser (from cffi!=1.11.3,>=1.7->cryptography>=2.2.1->pyopenssl->nsxramlclient>=2.0.1->pynsxv)
  Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB)
    100% |████████████████████████████████| 163kB 3.8MB/s 
Installing collected packages: six, pycparser, cffi, enum34, idna, asn1crypto, ipaddress, cryptography, pyopenssl, PyYAML, pyraml-parser, lxml, certifi, urllib3, chardet, requests, nsxramlclient, pyvmomi, tabulate, pynsxv
  Running setup.py install for pycparser ... done
  Running setup.py install for PyYAML ... done
  Running setup.py install for pyraml-parser ... done
  Running setup.py install for lxml ... done
  Running setup.py install for nsxramlclient ... done
  Running setup.py install for pyvmomi ... done
  Running setup.py install for tabulate ... done
  Running setup.py install for pynsxv ... done
Successfully installed PyYAML-3.13 asn1crypto-0.24.0 certifi-2018.10.15 cffi-1.11.5 chardet-3.0.4 cryptography-2.3.1 enum34-1.1.6 idna-2.7 ipaddress-1.0.22 lxml-3.6.0 nsxramlclient-2.0.7 pycparser-2.19 pynsxv-0.4.1 pyopenssl-18.0.0 pyraml-parser-0.1.7 pyvmomi-6.7.0.2018.9 requests-2.19.1 six-1.11.0 tabulate-0.8.2 urllib3-1.23

5. Using PyNSXv as a CLI Tool
After you installed PyNSXv, the first thing you have to do is to create an .ini file that contains the host names and credentials of your vCenter and NSX Manager.

If you have multiple NSX environments, you can create multiple .ini files and reference them using the -i command line option. By default PyNSXv will look for a file called nsx.ini in the path you are running the pynsxv command in.

# [nsxraml]

<h1>nsxraml_file = &lt;></h1>

<h1>Uncomment the above section and add the path to the raml spec you want to use instead of the bundled version</h1>

[nsxv]
nsx_manager = <nsx_manager_IP>
nsx_username = admin
nsx_password = <nsx_manager_password>

[vcenter]
vcenter = <VC_IP_or_Hostname>
vcenter_user = administrator@domain.local
vcenter_passwd = <vc_password>

[defaults]
transport_zone = <transport_zone_name>
datacenter_name = <vcenter datacenter name>
edge_datastore = <datastore name to deploy edges in>
edge_cluster = <vcenter cluster for edge gateways>

After placing the nsx.ini file in you path, you can run pynsxv from your shell or cmd prompt.

pynsxv -h
usage: pynsxv [-h] [-i INI] [-v] [-d] {lswitch,dlr,esg,dhcp,dfw,usage} ...

PyNSXv Command Line Client for NSX for vSphere

positional arguments:
  {lswitch,dlr,esg,dhcp,dfw,usage}
    lswitch             Functions for logical switches
    dlr                 Functions for distributed logical routers
    esg                 Functions for edge services gateways
    dhcp                Functions for Edge DHCP
    dfw                 Functions for distributed firewall
    usage               Functions to retrieve NSX-v usage statistics

optional arguments:
  -h, --help            show this help message and exit
  -i INI, --ini INI     nsx configuration file
  -v, --verbose         increase output verbosity
  -d, --debug           print low level debug of http transactions

Here is an example output using the lswitch subcommand

pynsxv lswitch list
+---------------------+----------------+
| LS name             | LS ID          |
|---------------------+----------------|
| edge_ls             | virtualwire-63 |
| dlr_ls              | virtualwire-64 |
+---------------------+----------------+

Each subcommand has its own set of subcommands, as well as arguments.
You can see what is available by using -h after the first subcommand.

pynsxv lswitch -h
usage: cli.py lswitch [-h] [-t TRANSPORT_ZONE] [-n NAME] command

Functions for logical switches

positional arguments:
  command
                            create: create a new logical switch
                            read:   return the virtual wire id of a logical switch
                            delete: delete a logical switch"
                            list:   return a list of all logical switches

optional arguments:
  -h, --help            show this help message and exit
  -t TRANSPORT_ZONE, --transport_zone TRANSPORT_ZONE
                        nsx transport zone
  -n NAME, --name NAME  logical switch name, needed for create, read and delete

You can also use the -v switch of the main pynsxv command to switch to a json formated output for use with shell scripts, which I’ll detail in my next post. How to Export/Import VMware NSX Distributed Firewall Rules, which is great way to migrate working lab DFW rulesets into production. …stay tuned for more!

How To Export VMware Licensing From vCenter Server

Here’s a helpful script to Export VMware Licensing From vCenter Server, which I wrote this back a bit ago and many of my VMware peers have found quite useful in the field. I finally got asked again by someone, so I decided to post it, instead of trying to email zipped code through antivirus systems. Enjoy! Happy licensing!

Script: http://www.virtuallyread.com/knowledge-base/getvmwarelicenses-ps1/

Disclaimer: ensure a semi-current Powershell / PowerCLI installation

Using the VMware Log Insight – Cisco ASA Content Pack to gain visibility and alerting

For those unaware, VMware Log Insight, is VMware’s syslog monitoring and alerting platform. It collects and automatically identifies structure in all types of machine-generated log data (application logs, network traces, configuration files, messages, performance data, system state dumps, etc.) to build a high performance index for performing analytics, so you can find pertinent information quickly.

With that being said, I do a lot of Log Insight use and am a big fan of the Content Packs that provide 3rd party integration. After showing this to clients for the last few months and having them rave about the dashboards and alerting in Log Insight, I decided to dedicate a post to configuring and using the Cisco ASA Content Pack for Log Insight.

The VMware Log Insight – Cisco ASA Content Pack provides new visibility, insight and alerting capabilities into firewall events, successful and denied connections, top source and destination dashboards for websites, bandwidth consumers, mail, chat, streaming, VPN connections and more. For a full overview of VMware Log Insight capabilities, check out the technical marketing material on the product site at https://www.vmware.com/products/vrealize-log-insight.html.

To configure your Cisco ASA for use with VMware Log Insight:

  1. Log into the Cisco ASA and enter configuration mode

  2. Configure the logging host

  3. Configure the logging trap level

  4. Configure the logging facility level

  5. Save the configuration

#logging host inside ip.of.log.insight
#logging trap informational
#logging facility 20

 

After configuring your ASA for use with Log Insight, you need to install the Cisco ASA Content Pack for Log Insight by clicking on the menu, which is the icon with three lines to the right of the username in the upper-right, then click Content Packs and then click on the Marketplace navigation on the upper-left of the screen as shown below. Find the Cisco ASA icon in the Log Insight Content Pack Marketplace and click it to install it.

 

 

After you’ve installed the Content Pack, log out of Log Insight and log back in. Navigate to the Content Pack Dashboards and click on the Cisco ASA Overview link.

The Cisco ASA Overview dashboard provides you with dashboards of All ASA Events over time with a histogram, a breakdown of events grouped by device, events by class and severity level, as well as, top destinations and sources. From here you can click on any graph and click Interactive Analytics to see a filtered view of the actual log events.

 

 

As you can see in the Interactive Analytics view of ASA events grouped by severity level, the Cisco ASA firewall is denying connection attempts for telnet to the outside interface of the firewall. The next thought is, “…geez, VMware, I wish I could easily setup an email alert for this filtered event on my Cisco ASA”. Well, I’m happy to add that WE CAN SETUP ALERTS IN LOG INSIGHT! YES!
 

 

Let’s take a look at how we setup a Log Insight alert for an event from our Cisco ASA.
To add an alert for Severity 3 events, go into the Interactive Analytics view for ASA events grouped by severity 3.

 

 

Click on Alerts, which is the red bell icon to the upper-right and then click on Create Alert from Query.

 

 

Fill in the New Alert form providing the name, description and recommendation, an email address or alias and then the criteria for the alert. You can match on any instance of an event, when an event is seen for the first time in the last x hours, or by how many occurrences happen in a given period and by group if desired. In any case, for this alert, I’d like to know anytime it’s more than one occurrence in five minutes.

 

 

Now that we’ve set an alert in Log Insight for our Cisco ASA, let’s take a look at some of the dashboards and information that the Content Pack provides visibility into.

 

Navigate to Denied Connections under the Cisco ASA Content Pack and you’re greeted by a dashboard of Top Denied Destinations, Top Denied Sources, Top Denied Protocol Groups and Top Denied Websites. Each of these can be drilled down into by right-clicking on a graph section and clicking Interactive Analytics to see the data. The Top Denied Sources is quite useful to determine where attacks are originating and can quickly provide you with a list of sources to take action on.
 

 

The Successful Connections Dashboard shows some really useful views of Top Accessed Destinations, Top Websites, a list of Latest Successful Connections and a graph of Reasons for successful TCP teardowns.

 

Besides looking to see that Facebook, Hulu or Youtube is probably the top accessed website from your firewall, the Latest Successful Connections is a great way to see if a new firewall rule or configuration change is working for clients accessing a new site or the like.

 

 

Clicking on the Traffic Overview dashboard reveals a fantastic histogram graph of bandwidth usage, which can be useful for forecasting and planning. The middle of the screen shows a graph of Top Connections With High Bandwidth Usage, to see who the big consumers are. Once again, you can drill down on any of those users to see what was being used. The user in this graph is my son’s Chromebook and I’m sure the bandwidth usage is from Youtube, no doubt. …was there any doubt? /grin
 

 

Lastly, the VPN Activity dashboard is great for analyzing past and for alerting on current VPN events. You can setup alerts for failed VPN connection attempts, which is always something to keep an eye on.

 

 

Wrapping it up, there’s quite a bit that VMware Log Insight can do for Cisco ASA users. The alerting capabilities for ASA events make Log Insight a great solution for environments where it’s deployed, as the Content Pack is free of charge, easily deployed and provides new visibility and “insights” into what’s happening on your ASA. …with or without you knowing. /grin