NSX|v3 use nsxlib in devstack cleanup

Refactor the devstack cleanup script to use nsxlib instead of accessing
the nsxmanager directly.
This patch is needed for the XSRF support.

Change-Id: Ib2e8c4031aae22f97f5a400d9dc5e49a945f7aed
This commit is contained in:
Adit Sarfaty 2017-08-28 11:49:31 +03:00
parent 340f413a3b
commit 9ac5edd12e
1 changed files with 81 additions and 199 deletions

View File

@ -13,17 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import base64
import optparse
from oslo_serialization import jsonutils
import requests
import six.moves.urllib.parse as urlparse
import sqlalchemy as sa
from vmware_nsx.db import nsx_models
requests.packages.urllib3.disable_warnings()
from vmware_nsxlib import v3
from vmware_nsxlib.v3 import config
class NeutronNsxDB(object):
@ -69,142 +65,29 @@ class NSXClient(object):
self.host = host
self.username = username
self.password = password
self.version = None
self.endpoint = None
self.content_type = "application/json"
self.accept_type = "application/json"
self.verify = False
self.secure = True
self.interface = "json"
self.url = None
self.headers = None
self.api_version = NSXClient.API_VERSION
self.neutron_db = (NeutronNsxDB(db_connection)
if db_connection else None)
self.__set_headers()
def __set_endpoint(self, endpoint):
self.endpoint = endpoint
def get_endpoint(self):
return self.endpoint
def __set_content_type(self, content_type):
self.content_type = content_type
def get_content_type(self):
return self.content_type
def __set_accept_type(self, accept_type):
self.accept_type = accept_type
def get_accept_type(self):
return self.accept_type
def __set_api_version(self, api_version):
self.api_version = api_version
def get_api_version(self):
return self.api
def __set_url(self, api=None, secure=None, host=None, endpoint=None):
api = self.api_version if api is None else api
secure = self.secure if secure is None else secure
host = self.host if host is None else host
endpoint = self.endpoint if endpoint is None else endpoint
http_type = 'https' if secure else 'http'
self.url = '%s://%s/api/%s%s' % (http_type, host, api, endpoint)
def get_url(self):
return self.url
def __set_headers(self, content=None, accept=None):
content_type = self.content_type if content is None else content
accept_type = self.accept_type if accept is None else accept
auth_cred = self.username + ":" + self.password
auth = base64.b64encode(auth_cred)
headers = {}
headers['Authorization'] = "Basic %s" % auth
headers['Content-Type'] = content_type
headers['Accept'] = accept_type
# allow admin user to delete entities created
# under openstack principal identity
headers['X-Allow-Overwrite'] = 'true'
self.headers = headers
def get(self, endpoint=None, params=None):
"""
Basic query method for json API request
"""
self.__set_url(endpoint=endpoint)
response = requests.get(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def get_list_results(self, endpoint=None, params=None):
"""
Query method for json API get for list (takes care of pagination)
"""
self.__set_url(endpoint=endpoint)
response = requests.get(self.url, headers=self.headers,
verify=self.verify, params=params).json()
results = response['results']
missing = response['result_count'] - len(results)
cursor = response.get('cursor', self.NULL_CURSOR_PREFIX)
op = '&' if urlparse.urlparse(self.url).query else '?'
url = self.url + op + 'cursor='
# we will enter the loop if response does not fit into single page
while missing > 0 and not cursor.startswith(self.NULL_CURSOR_PREFIX):
response = requests.get(url + cursor, headers=self.headers,
verify=self.verify, params=params).json()
cursor = response.get('cursor', self.NULL_CURSOR_PREFIX)
missing -= len(response['results'])
results += response['results']
return results
def put(self, endpoint=None, body=None):
"""
Basic put API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.put(self.url, headers=self.headers,
verify=self.verify, data=jsonutils.dumps(body))
return response
def delete(self, endpoint=None, params=None):
"""
Basic delete API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.delete(self.url, headers=self.headers,
verify=self.verify, params=params)
return response
def post(self, endpoint=None, body=None):
"""
Basic post API method on endpoint
"""
self.__set_url(endpoint=endpoint)
response = requests.post(self.url, headers=self.headers,
verify=self.verify,
data=jsonutils.dumps(body))
return response
nsxlib_config = config.NsxLibConfig(
username=self.username,
password=self.password,
nsx_api_managers=[self.host],
# allow admin user to delete entities created
# under openstack principal identity
allow_overwrite_header=True)
self.nsxlib = v3.NsxLib(nsxlib_config)
def get_transport_zones(self):
"""
Retrieve all transport zones
"""
return self.get_list_results(endpoint="/transport-zones")
return self.nsxlib.transport_zone.list()['results']
def get_logical_ports(self):
"""
Retrieve all logical ports on NSX backend
"""
return self.get_list_results(endpoint="/logical-ports")
return self.nsxlib.logical_port.list()['results']
def get_os_logical_ports(self):
"""
@ -223,17 +106,16 @@ class NSXClient(object):
the VIF attachment on the ports first.
"""
for p in lports:
p['attachment'] = None
endpoint = "/logical-ports/%s" % p['id']
response = self.put(endpoint=endpoint, body=p)
if response.status_code != requests.codes.ok:
print("ERROR: Failed to update lport %s" % p['id'])
try:
self.nsxlib.logical_port.update(
p['id'], None, attachment_type=None)
except Exception as e:
print("ERROR: Failed to update lport %s: %s" % p['id'], e)
def _remove_port_from_exclude_list(self, p):
try:
endpoint = ('/firewall/excludelist?action=remove_member&'
'object_id=%s' % p['id'])
self.post(endpoint)
self.nsxlib.firewall_section.remove_member_from_fw_exclude_list(
p['id'], None)
except Exception:
pass
@ -243,13 +125,13 @@ class NSXClient(object):
for p in lports:
# delete this port from the exclude list (if in it)
self._remove_port_from_exclude_list(p)
endpoint = '/logical-ports/%s' % p['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
print("Successfully deleted logical port %s" % p['id'])
try:
self.nsxlib.logical_port.delete(p['id'])
except Exception as e:
print("ERROR: Failed to delete logical port %s, error %s" %
(p['id'], e))
else:
print("ERROR: Failed to delete lport %s, response code %s" %
(p['id'], response.status_code))
print("Successfully deleted logical port %s" % p['id'])
def cleanup_os_logical_ports(self):
"""
@ -272,7 +154,7 @@ class NSXClient(object):
"""
Retrieve all logical switches on NSX backend
"""
return self.get_list_results(endpoint="/logical-switches")
return self.nsxlib.logical_switch.list()['results']
def get_os_logical_switches(self):
"""
@ -312,20 +194,20 @@ class NSXClient(object):
"deleted: %s" % len(lports))
self._cleanup_logical_ports(lports)
endpoint = '/logical-switches/%s' % ls['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
try:
self.nsxlib.logical_switch.delete(ls['id'])
except Exception as e:
print("ERROR: Failed to delete logical switch %s-%s, "
"error %s" % (ls['display_name'], ls['id'], e))
else:
print("Successfully deleted logical switch %s-%s" %
(ls['display_name'], ls['id']))
else:
print("Failed to delete lswitch %s-%s, and response is %s" %
(ls['display_name'], ls['id'], response.status_code))
def get_firewall_sections(self):
"""
Retrieve all firewall sections
"""
return self.get_list_results(endpoint="/firewall/sections")
return self.nsxlib.firewall_section.list()
def get_os_firewall_sections(self):
"""
@ -347,21 +229,21 @@ class NSXClient(object):
print("Number of OS Firewall Sections to be deleted: %s" %
len(fw_sections))
for fw in fw_sections:
endpoint = "/firewall/sections/%s?cascade=true" % fw['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
print("Successfully deleted firewall section %s" %
fw['display_name'])
try:
self.nsxlib.firewall_section.delete(fw['id'])
except Exception as e:
print("Failed to delete firewall section %s: %s" %
(fw['display_name'], e))
else:
print("Failed to delete firewall section %s" %
print("Successfully deleted firewall section %s" %
fw['display_name'])
def get_ns_groups(self):
"""
Retrieve all NSGroups on NSX backend
"""
ns_groups = self.get_os_resources(
self.get_list_results(endpoint="/ns-groups"))
backend_groups = self.nsxlib.ns_group.list()
ns_groups = self.get_os_resources(backend_groups)
if self.neutron_db:
db_nsgroups = self.neutron_db.get_nsgroups()
ns_groups = [nsg for nsg in ns_groups
@ -375,18 +257,20 @@ class NSXClient(object):
ns_groups = self.get_ns_groups()
print("Number of OS NSGroups to be deleted: %s" % len(ns_groups))
for nsg in ns_groups:
endpoint = "/ns-groups/%s?force=true" % nsg['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
print("Successfully deleted NSGroup: %s" % nsg['display_name'])
try:
self.nsxlib.ns_group.delete(nsg['id'])
except Exception as e:
print("Failed to delete NSGroup: %s: %s" %
(nsg['display_name'], e))
else:
print("Failed to delete NSGroup: %s" % nsg['display_name'])
print("Successfully deleted NSGroup: %s" %
nsg['display_name'])
def get_switching_profiles(self):
"""
Retrieve all Switching Profiles on NSX backend
"""
return self.get_list_results(endpoint="/switching-profiles")
return self.nsxlib.switching_profile.list()['results']
def get_os_switching_profiles(self):
"""
@ -406,13 +290,13 @@ class NSXClient(object):
print("Number of OS SwitchingProfiles to be deleted: %s" %
len(sw_profiles))
for swp in sw_profiles:
endpoint = "/switching-profiles/%s" % swp['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
print("Successfully deleted Switching Profile: %s" %
swp['display_name'])
try:
self.nsxlib.switching_profile.delete(swp['id'])
except Exception as e:
print("Failed to delete Switching Profile: %s: %s" %
(swp['display_name'], e))
else:
print("Failed to delete Switching Profile: %s" %
print("Successfully deleted Switching Profile: %s" %
swp['display_name'])
def get_logical_routers(self, tier=None):
@ -420,11 +304,8 @@ class NSXClient(object):
Retrieve all the logical routers based on router type. If tier
is None, it will return all logical routers.
"""
if tier:
endpoint = "/logical-routers?router_type=%s" % tier
else:
endpoint = "/logical-routers"
lrouters = self.get_list_results(endpoint=endpoint)
lrouters = self.nsxlib.logical_router.list(
router_type=tier)['results']
if self.neutron_db:
db_routers = self.neutron_db.get_logical_routers()
@ -434,7 +315,7 @@ class NSXClient(object):
def get_os_logical_routers(self):
"""
Retrive all logical routers created from Neutron NSXv3 plugin
Retrieve all logical routers created from Neutron NSXv3 plugin
"""
lrouters = self.get_logical_routers()
return self.get_os_resources(lrouters)
@ -443,8 +324,7 @@ class NSXClient(object):
"""
Get all logical ports attached to lrouter
"""
endpoint = "/logical-router-ports?logical_router_id=%s" % lrouter['id']
return self.get_list_results(endpoint=endpoint)
return self.nsxlib.logical_router_port.get_by_router_id(lrouter['id'])
def get_os_logical_router_ports(self, lrouter):
"""
@ -459,14 +339,15 @@ class NSXClient(object):
"""
lports = self.get_os_logical_router_ports(lrouter)
for lp in lports:
endpoint = "/logical-router-ports/%s" % lp['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
try:
self.nsxlib.logical_router_port.delete(lp['id'])
except Exception as e:
print("Failed to delete logical router port %s-%s, "
"and response is %s" %
(lp['display_name'], lp['id'], e))
else:
print("Successfully deleted logical router port %s-%s" %
(lp['display_name'], lp['id']))
else:
print("Failed to delete lr port %s-%s, and response is %s" %
(lp['display_name'], lp['id'], response))
def cleanup_os_logical_routers(self):
"""
@ -479,14 +360,15 @@ class NSXClient(object):
len(lrouters))
for lr in lrouters:
self.cleanup_logical_router_ports(lr)
endpoint = "/logical-routers/%s" % lr['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
try:
self.nsxlib.logical_router.delete(lr['id'])
except Exception as e:
print("ERROR: Failed to delete logical router %s-%s, "
"error %s" % (lr['display_name'], lr['id'], e))
else:
print("Successfully deleted logical router %s-%s" %
(lr['display_name'], lr['id']))
else:
print("Failed to delete lrouter %s-%s, and response is %s" %
(lr['display_name'], lr['id'], response))
def cleanup_os_tier0_logical_ports(self):
"""
@ -500,7 +382,7 @@ class NSXClient(object):
"""
Retrieve all logical DHCP servers on NSX backend
"""
return self.get_list_results(endpoint="/dhcp/servers")
return self.nsxlib.dhcp_server.list()['results']
def get_os_logical_dhcp_servers(self):
"""
@ -523,13 +405,13 @@ class NSXClient(object):
print("Number of OS Logical DHCP Servers to be deleted: %s" %
len(dhcp_servers))
for server in dhcp_servers:
endpoint = "/dhcp/servers/%s" % server['id']
response = self.delete(endpoint=endpoint)
if response.status_code == requests.codes.ok:
print("Successfully deleted logical DHCP server: %s" %
server['display_name'])
try:
self.nsxlib.dhcp_server.delete(server['id'])
except Exception as e:
print("ERROR: Failed to delete logical DHCP server %s, "
"error %s" % (server['display_name'], e))
else:
print("Failed to delete logical DHCP server: %s" %
print("Successfully deleted logical DHCP server %s" %
server['display_name'])
def cleanup_all(self):