def _create_resource_class(self, name): """Calls the placement API to create a new resource class. :param name: String name of the resource class to create. :returns: None on successful creation. :raises: `exception.InvalidResourceClass` upon error. """ url = "/resource_classes" payload = { 'name': name, } resp = self.post(url, payload, version="1.2") if 200 <= resp.status_code < 300: msg = ("Created resource class record via placement API " "for resource class %s.") LOG.info(msg, name) elif resp.status_code == 409: # Another thread concurrently created a resource class with the # same name. Log a warning and then just return msg = ("Another thread already created a resource class " "with the name %s. Returning.") LOG.info(msg, name) else: msg = ("Failed to create resource class %(resource_class)s in " "placement API. Got %(status_code)d: %(err_text)s.") args = { 'resource_class': name, 'status_code': resp.status_code, 'err_text': resp.text, } LOG.error(msg, args) raise exception.InvalidResourceClass(resource_class=name)
def _ensure_resource_class(self, name): """Make sure a custom resource class exists. First attempt to PUT the resource class using microversion 1.7. If this results in a 406, fail over to a GET and POST with version 1.2. Returns the name of the resource class if it was successfully created or already exists. Otherwise None. :param name: String name of the resource class to check/create. :raises: `exception.InvalidResourceClass` upon error. """ # no payload on the put request response = self.put("/resource_classes/%s" % name, None, version="1.7") if 200 <= response.status_code < 300: return name elif response.status_code == 406: # microversion 1.7 not available so try the earlier way # TODO(cdent): When we're happy that all placement # servers support microversion 1.7 we can remove this # call and the associated code. LOG.debug('Falling back to placement API microversion 1.2 ' 'for resource class management.') return self._get_or_create_resource_class(name) else: msg = ("Failed to ensure resource class record with " "placement API for resource class %(rc_name)s. " "Got %(status_code)d: %(err_text)s.") args = { 'rc_name': name, 'status_code': response.status_code, 'err_text': response.text, } LOG.error(msg, args) raise exception.InvalidResourceClass(resource_class=name)