NSX|V: add in edge resource configuration support

Version 6.2.3 enables on to configure edge resources. This patch
ensures that no reservations will take place. This will also
enable us in the future to expose this feature.

The patch also adds in a utility that can be run out of band. This
can be done if the NSX is upgraded to 6.2.3 and the plugin will
not need to be restarted.

Change-Id: I19a8e7371047f1e274dddf8d734b126289167fad
This commit is contained in:
Gary Kotton 2016-03-13 01:00:37 -08:00
parent 03eea64ef9
commit ae8184fa15
4 changed files with 143 additions and 0 deletions

View File

@ -0,0 +1,110 @@
#!/usr/bin/env python
# Copyright 2015 VMware Inc
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Purpose: Configure edge resource limits
Usage:
python nsxv_edge_resources.py --vsm-ip <nsx-manager-ip>
--username <nsx-manager-username>
--password <nsx-manager-password>
"""
import base64
import optparse
from oslo_serialization import jsonutils
import requests
import six
import xml.etree.ElementTree as et
requests.packages.urllib3.disable_warnings()
class NSXClient(object):
def __init__(self, host, username, password, *args, **kwargs):
self._host = host
self._username = username
self._password = password
def _get_headers(self, format):
auth_cred = self._username + ":" + self._password
auth = base64.b64encode(auth_cred)
headers = {}
headers['Authorization'] = "Basic %s" % auth
headers['Content-Type'] = "application/%s" % format
headers['Accept'] = "application/%s" % format
return headers
def _get_url(self, uri):
return 'https://%s/%s' % (self._host, uri)
def _get(self, format, uri):
headers = self._get_headers(format)
url = self._get_url(uri)
response = requests.get(url, headers=headers,
verify=False)
return response
def _put(self, format, uri, data):
headers = self._get_headers(format)
url = self._get_url(uri)
response = requests.put(url, headers=headers,
verify=False, data=data)
return response
def _get_tuning_configration(self):
response = self._get("json",
"/api/4.0/edgePublish/tuningConfiguration")
return jsonutils.loads(response.text)
def configure_reservations(self):
config = self._get_tuning_configration()
# NSX only receive XML format for the resource allocation update
tuning = et.Element('tuningConfiguration')
for opt, val in six.iteritems(config):
child = et.Element(opt)
if (opt == 'edgeVCpuReservationPercentage' or
opt == 'edgeMemoryReservationPercentage'):
child.text = '0'
elif opt == 'megaHertzPerVCpu':
child.text = '1500'
else:
child.text = str(val)
tuning.append(child)
self._put("xml",
"/api/4.0/edgePublish/tuningConfiguration",
et.tostring(tuning))
print ("Edge resource limits set")
if __name__ == "__main__":
parser = optparse.OptionParser()
parser.add_option("--vsm-ip", dest="vsm_ip", help="NSX Manager IP address")
parser.add_option("-u", "--username", default="admin", dest="username",
help="NSX Manager username")
parser.add_option("-p", "--password", default="default", dest="password",
help="NSX Manager password")
(options, args) = parser.parse_args()
print ("vsm-ip: %s" % options.vsm_ip)
print ("username: %s" % options.username)
print ("password: %s" % options.password)
nsx_client = NSXClient(options.vsm_ip, options.username,
options.password)
nsx_client.configure_reservations()

View File

@ -188,6 +188,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._ensure_lock_operations() self._ensure_lock_operations()
# Configure aggregate publishing # Configure aggregate publishing
self._aggregate_publishing() self._aggregate_publishing()
# Configure edge reservations
self._configure_reservations()
self.edge_manager = edge_utils.EdgeManager(self.nsx_v, self) self.edge_manager = edge_utils.EdgeManager(self.nsx_v, self)
self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id self.vdn_scope_id = cfg.CONF.nsxv.vdn_scope_id
self.dvs_id = cfg.CONF.nsxv.dvs_id self.dvs_id = cfg.CONF.nsxv.dvs_id
@ -2972,6 +2974,17 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
except Exception: except Exception:
LOG.info(_LI("Unable to configure aggregate publishing")) LOG.info(_LI("Unable to configure aggregate publishing"))
def _configure_reservations(self):
ver = self.nsx_v.vcns.get_version()
if version.LooseVersion(ver) < version.LooseVersion('6.2.3'):
LOG.debug("Skipping reservation configuration. "
"Not supported by version - %s.", ver)
return
try:
self.nsx_v.vcns.configure_reservations()
except Exception:
LOG.info(_LI("Unable to configure edge reservations"))
def _validate_config(self): def _validate_config(self):
if (cfg.CONF.nsxv.dvs_id and if (cfg.CONF.nsxv.dvs_id and
not self.nsx_v.vcns.validate_dvs(cfg.CONF.nsxv.dvs_id)): not self.nsx_v.vcns.validate_dvs(cfg.CONF.nsxv.dvs_id)):

View File

@ -878,6 +878,23 @@ class Vcns(object):
return self.do_request(HTTP_PUT, uri, et.tostring(tuning), return self.do_request(HTTP_PUT, uri, et.tostring(tuning),
format='xml', decode=True) format='xml', decode=True)
def configure_reservations(self):
uri = "/api/4.0/edgePublish/tuningConfiguration"
config = self.get_tuning_configration()
tuning = et.Element('tuningConfiguration')
for opt, val in six.iteritems(config):
child = et.Element(opt)
if (opt == 'edgeVCpuReservationPercentage' or
opt == 'edgeMemoryReservationPercentage'):
child.text = '0'
elif opt == 'megaHertzPerVCpu':
child.text = '1500'
else:
child.text = str(val)
tuning.append(child)
return self.do_request(HTTP_PUT, uri, et.tostring(tuning),
format='xml', decode=True)
def enable_ha(self, edge_id, request_config, async=True): def enable_ha(self, edge_id, request_config, async=True):
"""Enable HA in the given edge.""" """Enable HA in the given edge."""
uri = "/api/4.0/edges/%s/highavailability/config" % edge_id uri = "/api/4.0/edges/%s/highavailability/config" % edge_id

View File

@ -1069,6 +1069,9 @@ class FakeVcns(object):
def publish_assigned_addresses(self, policy_id, vnic_id): def publish_assigned_addresses(self, policy_id, vnic_id):
pass pass
def configure_reservations(self):
pass
def inactivate_vnic_assigned_addresses(self, policy_id, vnic_id): def inactivate_vnic_assigned_addresses(self, policy_id, vnic_id):
pass pass