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.
(cherry picked from commit 9ac5edd12e
)
Change-Id: I6bc4f68412331fb4b1de1f5da1c6660fb608e86e
This commit is contained in:
parent
aa8e690326
commit
aea205b69d
|
@ -13,17 +13,12 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import base64
|
|
||||||
import optparse
|
import optparse
|
||||||
import requests
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
from oslo_serialization import jsonutils
|
|
||||||
import six.moves.urllib.parse as urlparse
|
|
||||||
from vmware_nsx.db import nsx_models
|
from vmware_nsx.db import nsx_models
|
||||||
|
from vmware_nsxlib import v3
|
||||||
|
from vmware_nsxlib.v3 import config
|
||||||
requests.packages.urllib3.disable_warnings()
|
|
||||||
|
|
||||||
|
|
||||||
class NeutronNsxDB(object):
|
class NeutronNsxDB(object):
|
||||||
|
@ -69,142 +64,29 @@ class NSXClient(object):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
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)
|
self.neutron_db = (NeutronNsxDB(db_connection)
|
||||||
if db_connection else None)
|
if db_connection else None)
|
||||||
|
|
||||||
self.__set_headers()
|
nsxlib_config = config.NsxLibConfig(
|
||||||
|
username=self.username,
|
||||||
def __set_endpoint(self, endpoint):
|
password=self.password,
|
||||||
self.endpoint = endpoint
|
nsx_api_managers=[self.host],
|
||||||
|
# allow admin user to delete entities created
|
||||||
def get_endpoint(self):
|
# under openstack principal identity
|
||||||
return self.endpoint
|
allow_overwrite_header=True)
|
||||||
|
self.nsxlib = v3.NsxLib(nsxlib_config)
|
||||||
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
|
|
||||||
|
|
||||||
def get_transport_zones(self):
|
def get_transport_zones(self):
|
||||||
"""
|
"""
|
||||||
Retrieve all transport zones
|
Retrieve all transport zones
|
||||||
"""
|
"""
|
||||||
return self.get_list_results(endpoint="/transport-zones")
|
return self.nsxlib.transport_zone.list()['results']
|
||||||
|
|
||||||
def get_logical_ports(self):
|
def get_logical_ports(self):
|
||||||
"""
|
"""
|
||||||
Retrieve all logical ports on NSX backend
|
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):
|
def get_os_logical_ports(self):
|
||||||
"""
|
"""
|
||||||
|
@ -223,17 +105,16 @@ class NSXClient(object):
|
||||||
the VIF attachment on the ports first.
|
the VIF attachment on the ports first.
|
||||||
"""
|
"""
|
||||||
for p in lports:
|
for p in lports:
|
||||||
p['attachment'] = None
|
try:
|
||||||
endpoint = "/logical-ports/%s" % p['id']
|
self.nsxlib.logical_port.update(
|
||||||
response = self.put(endpoint=endpoint, body=p)
|
p['id'], None, attachment_type=None)
|
||||||
if response.status_code != requests.codes.ok:
|
except Exception as e:
|
||||||
print("ERROR: Failed to update lport %s" % p['id'])
|
print("ERROR: Failed to update lport %s: %s" % p['id'], e)
|
||||||
|
|
||||||
def _remove_port_from_exclude_list(self, p):
|
def _remove_port_from_exclude_list(self, p):
|
||||||
try:
|
try:
|
||||||
endpoint = ('/firewall/excludelist?action=remove_member&'
|
self.nsxlib.firewall_section.remove_member_from_fw_exclude_list(
|
||||||
'object_id=%s' % p['id'])
|
p['id'], None)
|
||||||
self.post(endpoint)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -243,13 +124,13 @@ class NSXClient(object):
|
||||||
for p in lports:
|
for p in lports:
|
||||||
# delete this port from the exclude list (if in it)
|
# delete this port from the exclude list (if in it)
|
||||||
self._remove_port_from_exclude_list(p)
|
self._remove_port_from_exclude_list(p)
|
||||||
endpoint = '/logical-ports/%s' % p['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.logical_port.delete(p['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
except Exception as e:
|
||||||
print("Successfully deleted logical port %s" % p['id'])
|
print("ERROR: Failed to delete logical port %s, error %s" %
|
||||||
|
(p['id'], e))
|
||||||
else:
|
else:
|
||||||
print("ERROR: Failed to delete lport %s, response code %s" %
|
print("Successfully deleted logical port %s" % p['id'])
|
||||||
(p['id'], response.status_code))
|
|
||||||
|
|
||||||
def cleanup_os_logical_ports(self):
|
def cleanup_os_logical_ports(self):
|
||||||
"""
|
"""
|
||||||
|
@ -272,7 +153,7 @@ class NSXClient(object):
|
||||||
"""
|
"""
|
||||||
Retrieve all logical switches on NSX backend
|
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):
|
def get_os_logical_switches(self):
|
||||||
"""
|
"""
|
||||||
|
@ -312,20 +193,20 @@ class NSXClient(object):
|
||||||
"deleted: %s" % len(lports))
|
"deleted: %s" % len(lports))
|
||||||
self._cleanup_logical_ports(lports)
|
self._cleanup_logical_ports(lports)
|
||||||
|
|
||||||
endpoint = '/logical-switches/%s' % ls['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.logical_switch.delete(ls['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
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" %
|
print("Successfully deleted logical switch %s-%s" %
|
||||||
(ls['display_name'], ls['id']))
|
(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):
|
def get_firewall_sections(self):
|
||||||
"""
|
"""
|
||||||
Retrieve all firewall sections
|
Retrieve all firewall sections
|
||||||
"""
|
"""
|
||||||
return self.get_list_results(endpoint="/firewall/sections")
|
return self.nsxlib.firewall_section.list()
|
||||||
|
|
||||||
def get_os_firewall_sections(self):
|
def get_os_firewall_sections(self):
|
||||||
"""
|
"""
|
||||||
|
@ -347,21 +228,21 @@ class NSXClient(object):
|
||||||
print("Number of OS Firewall Sections to be deleted: %s" %
|
print("Number of OS Firewall Sections to be deleted: %s" %
|
||||||
len(fw_sections))
|
len(fw_sections))
|
||||||
for fw in fw_sections:
|
for fw in fw_sections:
|
||||||
endpoint = "/firewall/sections/%s?cascade=true" % fw['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.firewall_section.delete(fw['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
except Exception as e:
|
||||||
print("Successfully deleted firewall section %s" %
|
print("Failed to delete firewall section %s: %s" %
|
||||||
fw['display_name'])
|
(fw['display_name'], e))
|
||||||
else:
|
else:
|
||||||
print("Failed to delete firewall section %s" %
|
print("Successfully deleted firewall section %s" %
|
||||||
fw['display_name'])
|
fw['display_name'])
|
||||||
|
|
||||||
def get_ns_groups(self):
|
def get_ns_groups(self):
|
||||||
"""
|
"""
|
||||||
Retrieve all NSGroups on NSX backend
|
Retrieve all NSGroups on NSX backend
|
||||||
"""
|
"""
|
||||||
ns_groups = self.get_os_resources(
|
backend_groups = self.nsxlib.ns_group.list()
|
||||||
self.get_list_results(endpoint="/ns-groups"))
|
ns_groups = self.get_os_resources(backend_groups)
|
||||||
if self.neutron_db:
|
if self.neutron_db:
|
||||||
db_nsgroups = self.neutron_db.get_nsgroups()
|
db_nsgroups = self.neutron_db.get_nsgroups()
|
||||||
ns_groups = [nsg for nsg in ns_groups
|
ns_groups = [nsg for nsg in ns_groups
|
||||||
|
@ -375,18 +256,20 @@ class NSXClient(object):
|
||||||
ns_groups = self.get_ns_groups()
|
ns_groups = self.get_ns_groups()
|
||||||
print("Number of OS NSGroups to be deleted: %s" % len(ns_groups))
|
print("Number of OS NSGroups to be deleted: %s" % len(ns_groups))
|
||||||
for nsg in ns_groups:
|
for nsg in ns_groups:
|
||||||
endpoint = "/ns-groups/%s?force=true" % nsg['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.ns_group.delete(nsg['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
except Exception as e:
|
||||||
print("Successfully deleted NSGroup: %s" % nsg['display_name'])
|
print("Failed to delete NSGroup: %s: %s" %
|
||||||
|
(nsg['display_name'], e))
|
||||||
else:
|
else:
|
||||||
print("Failed to delete NSGroup: %s" % nsg['display_name'])
|
print("Successfully deleted NSGroup: %s" %
|
||||||
|
nsg['display_name'])
|
||||||
|
|
||||||
def get_switching_profiles(self):
|
def get_switching_profiles(self):
|
||||||
"""
|
"""
|
||||||
Retrieve all Switching Profiles on NSX backend
|
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):
|
def get_os_switching_profiles(self):
|
||||||
"""
|
"""
|
||||||
|
@ -406,13 +289,13 @@ class NSXClient(object):
|
||||||
print("Number of OS SwitchingProfiles to be deleted: %s" %
|
print("Number of OS SwitchingProfiles to be deleted: %s" %
|
||||||
len(sw_profiles))
|
len(sw_profiles))
|
||||||
for swp in sw_profiles:
|
for swp in sw_profiles:
|
||||||
endpoint = "/switching-profiles/%s" % swp['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.switching_profile.delete(swp['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
except Exception as e:
|
||||||
print("Successfully deleted Switching Profile: %s" %
|
print("Failed to delete Switching Profile: %s: %s" %
|
||||||
swp['display_name'])
|
(swp['display_name'], e))
|
||||||
else:
|
else:
|
||||||
print("Failed to delete Switching Profile: %s" %
|
print("Successfully deleted Switching Profile: %s" %
|
||||||
swp['display_name'])
|
swp['display_name'])
|
||||||
|
|
||||||
def get_logical_routers(self, tier=None):
|
def get_logical_routers(self, tier=None):
|
||||||
|
@ -420,11 +303,8 @@ class NSXClient(object):
|
||||||
Retrieve all the logical routers based on router type. If tier
|
Retrieve all the logical routers based on router type. If tier
|
||||||
is None, it will return all logical routers.
|
is None, it will return all logical routers.
|
||||||
"""
|
"""
|
||||||
if tier:
|
lrouters = self.nsxlib.logical_router.list(
|
||||||
endpoint = "/logical-routers?router_type=%s" % tier
|
router_type=tier)['results']
|
||||||
else:
|
|
||||||
endpoint = "/logical-routers"
|
|
||||||
lrouters = self.get_list_results(endpoint=endpoint)
|
|
||||||
|
|
||||||
if self.neutron_db:
|
if self.neutron_db:
|
||||||
db_routers = self.neutron_db.get_logical_routers()
|
db_routers = self.neutron_db.get_logical_routers()
|
||||||
|
@ -434,7 +314,7 @@ class NSXClient(object):
|
||||||
|
|
||||||
def get_os_logical_routers(self):
|
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()
|
lrouters = self.get_logical_routers()
|
||||||
return self.get_os_resources(lrouters)
|
return self.get_os_resources(lrouters)
|
||||||
|
@ -443,8 +323,7 @@ class NSXClient(object):
|
||||||
"""
|
"""
|
||||||
Get all logical ports attached to lrouter
|
Get all logical ports attached to lrouter
|
||||||
"""
|
"""
|
||||||
endpoint = "/logical-router-ports?logical_router_id=%s" % lrouter['id']
|
return self.nsxlib.logical_router_port.get_by_router_id(lrouter['id'])
|
||||||
return self.get_list_results(endpoint=endpoint)
|
|
||||||
|
|
||||||
def get_os_logical_router_ports(self, lrouter):
|
def get_os_logical_router_ports(self, lrouter):
|
||||||
"""
|
"""
|
||||||
|
@ -459,14 +338,15 @@ class NSXClient(object):
|
||||||
"""
|
"""
|
||||||
lports = self.get_os_logical_router_ports(lrouter)
|
lports = self.get_os_logical_router_ports(lrouter)
|
||||||
for lp in lports:
|
for lp in lports:
|
||||||
endpoint = "/logical-router-ports/%s" % lp['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.logical_router_port.delete(lp['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
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" %
|
print("Successfully deleted logical router port %s-%s" %
|
||||||
(lp['display_name'], lp['id']))
|
(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):
|
def cleanup_os_logical_routers(self):
|
||||||
"""
|
"""
|
||||||
|
@ -479,14 +359,15 @@ class NSXClient(object):
|
||||||
len(lrouters))
|
len(lrouters))
|
||||||
for lr in lrouters:
|
for lr in lrouters:
|
||||||
self.cleanup_logical_router_ports(lr)
|
self.cleanup_logical_router_ports(lr)
|
||||||
endpoint = "/logical-routers/%s" % lr['id']
|
|
||||||
response = self.delete(endpoint=endpoint)
|
try:
|
||||||
if response.status_code == requests.codes.ok:
|
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" %
|
print("Successfully deleted logical router %s-%s" %
|
||||||
(lr['display_name'], lr['id']))
|
(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):
|
def cleanup_os_tier0_logical_ports(self):
|
||||||
"""
|
"""
|
||||||
|
@ -500,7 +381,7 @@ class NSXClient(object):
|
||||||
"""
|
"""
|
||||||
Retrieve all logical DHCP servers on NSX backend
|
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):
|
def get_os_logical_dhcp_servers(self):
|
||||||
"""
|
"""
|
||||||
|
@ -523,13 +404,13 @@ class NSXClient(object):
|
||||||
print("Number of OS Logical DHCP Servers to be deleted: %s" %
|
print("Number of OS Logical DHCP Servers to be deleted: %s" %
|
||||||
len(dhcp_servers))
|
len(dhcp_servers))
|
||||||
for server in dhcp_servers:
|
for server in dhcp_servers:
|
||||||
endpoint = "/dhcp/servers/%s" % server['id']
|
try:
|
||||||
response = self.delete(endpoint=endpoint)
|
self.nsxlib.dhcp_server.delete(server['id'])
|
||||||
if response.status_code == requests.codes.ok:
|
except Exception as e:
|
||||||
print("Successfully deleted logical DHCP server: %s" %
|
print("ERROR: Failed to delete logical DHCP server %s, "
|
||||||
server['display_name'])
|
"error %s" % (server['display_name'], e))
|
||||||
else:
|
else:
|
||||||
print("Failed to delete logical DHCP server: %s" %
|
print("Successfully deleted logical DHCP server %s" %
|
||||||
server['display_name'])
|
server['display_name'])
|
||||||
|
|
||||||
def cleanup_all(self):
|
def cleanup_all(self):
|
||||||
|
|
Loading…
Reference in New Issue