def updatePriority(self, user): if self.isClosed(): raise SynergyError("the queue is closed!") if self.getType() != "PRIORITY": raise SynergyError("updatePriority() cannot be applied on this " "queue type") new_items = [] with self.condition: while self._items: item = heapq.heappop(self._items)[2] if item.getUserId() == user.getId() and\ item.getProjectId() == user.getProjectId(): item.setPriority(user.getPriority().getValue()) new_items.append(item) for item in new_items: heapq.heappush( self._items, (-item.getPriority(), item.getCreationTime(), item)) self.condition.notifyAll()
def enqueue(self, user, data): if self.isClosed(): raise SynergyError("the queue is closed!") if not user: raise SynergyError("user not specified!") if not data: raise SynergyError("data not specified!") item = QueueItem() item.setUserId(user.getId()) item.setProjectId(user.getProjectId()) item.setPriority(user.getPriority().getValue()) item.setData(data) with self.condition: if self.getType() == "FIFO": self._items.append(item) elif self.getType() == "LIFO": self._items.insert(0, item) elif self.getType() == "PRIORITY": heapq.heappush( self._items, (-item.getPriority(), item.getCreationTime(), item)) self._insertItemDB(item) self._incSize(1) self.condition.notifyAll()
def getUserData(self, server): if not server: return None secret = CONF.NovaManager.metadata_proxy_shared_secret if not secret: raise SynergyError("'metadata_proxy_shared_secret' " "attribute not defined in synergy.conf") digest = hmac.new(secret, server.getId(), hashlib.sha256).hexdigest() self.keystone_manager.authenticate() token = self.keystone_manager.getToken() service = token.getService("nova") if not service: raise SynergyError("nova service not found!") endpoint = service.getEndpoint("public") if not endpoint: raise SynergyError("nova endpoint not found!") url = endpoint.getURL() url = url[:url.rfind(":") + 1] + "8775/openstack/2015-10-15/user_data" headers = { "Content-Type": "application/text", "Accept": "application/text", "User-Agent": "synergy", "x-instance-id": server.getId(), "x-tenant-id": server.getProjectId(), "x-instance-id-signature": digest } request = requests.get(url, headers=headers, timeout=self.timeout, verify=self.ssl_ca_file, cert=self.ssl_cert_file) if request.status_code != requests.codes.ok: if request.status_code == 404: return None elif request.status_code == 403: if "Invalid proxy request signature" in request._content: raise SynergyError("cannot retrieve the 'userdata' value: " "check the 'metadata_proxy_shared_" "secret' attribute value") else: request.raise_for_status() else: request.raise_for_status() if request.text: return request.text else: return None
def deleteTrust(self, id, token=None): if not token: token = self.getToken() if token.isExpired(): raise SynergyError("token expired!") try: self.getResource("/OS-TRUST/trusts/%s" % id, "DELETE", token=token) except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError("error on deleting the trust (id=%r): %s" % (id, response["error"]["message"]))
def setup(self): if self.getManager("NovaManager") is None: raise SynergyError("NovaManager not found!") if self.getManager("KeystoneManager") is None: raise SynergyError("KeystoneManager not found!") if self.getManager("ProjectManager") is None: raise SynergyError("ProjectManager not found!") self.nova_manager = self.getManager("NovaManager") self.keystone_manager = self.getManager("KeystoneManager") self.project_manager = self.getManager("ProjectManager")
def createTable(self): TABLE = """CREATE TABLE IF NOT EXISTS project (`id` VARCHAR(64) \ NOT NULL PRIMARY KEY, name VARCHAR(64), share INT DEFAULT 0, TTL INT DEFAULT \ 1440) ENGINE=InnoDB""" connection = self.db_engine.connect() try: connection.execute(TABLE) except SQLAlchemyError as ex: raise SynergyError(ex.message) except Exception as ex: raise SynergyError(ex.message) finally: connection.close()
def dequeue(self, block=True, timeout=None, delete=False): if self.isClosed(): raise SynergyError("the queue is closed!") item = None with self.condition: while (item is None and not self.isClosed()): if not self._items: if block: self.condition.wait(timeout) if timeout: break else: break elif self.getType() == "PRIORITY": item = heapq.heappop(self._items)[2] else: item = self._items.pop(0) self.condition.notifyAll() if not item: return None self._getItemDataDB(item) if delete: self.delete(item) return item
def getServices(self): try: response = self.getResource("/services", "GET") except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError("error on retrieving the services list: %s" % response["error"]["message"]) services = [] if response: services_info = response["services"] for info in services_info: service = Service() service.setId(info["id"]) service.setName(info["name"]) service.setType(info["type"]) service.setDescription(info["description"]) service.setEnabled(info["enabled"]) for endpoint_info in service.get("endpoints"): endpoint = Endpoint() endpoint.setId(endpoint_info["id"]) endpoint.setInterface(endpoint_info["interface"]) endpoint.setRegion(endpoint_info["region"]) endpoint.setRegionId(endpoint_info["region_id"]) endpoint.setURL(endpoint_info["url"]) service.getEndpoints().append(endpoint) services.append(service) return services
def getEndpoints(self): try: response = self.getResource("/endpoints", "GET") except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError("error on retrieving the endpoints list: %s" % response["error"]["message"]) endpoints = [] if response: endpoints_info = response["endpoints"] for info in endpoints_info: endpoint = Endpoint() endpoint.setId(info["id"]) endpoint.setName(info["name"]) endpoint.setInterface(info["interface"]) endpoint.setRegion(info["region"]) endpoint.setRegionId(info["region_id"]) endpoint.setServiceId(info["service_id"]) endpoint.setURL(info["url"]) endpoint.setEnabled(info["enabled"]) endpoints.append(endpoint) return endpoints
def validateToken(self, id): self.authenticate() headers = { "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "synergy", "X-Auth-Project-Id": self.token.getProject().getName(), "X-Auth-Token": self.token.getId(), "X-Subject-Token": id } response = requests.get(url=self.auth_url + "/auth/tokens", headers=headers, timeout=self.timeout) if response.status_code != requests.codes.ok: response.raise_for_status() if not response.text: raise SynergyError("token not found!") token_subject = response.headers["X-Subject-Token"] token_data = response.json() return Token.parse(token_subject, token_data)
def getTrusts(self, user_id=None, isTrustor=True, token=None): url = "/OS-TRUST/trusts" data = None if user_id: if isTrustor: data = {"trustor_user_id": user_id} else: data = {"trustee_user_id": user_id} try: response = self.getResource(url, "GET", token=token, data=data) except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError( "error on retrieving the trust list (id=%r): %s" % (id, response["error"]["message"])) trusts = [] if response: for data in response["trusts"]: trust = Trust(data) trust.keystone_url = self.auth_url trust.ssl_ca_file = self.ssl_ca_file trust.ssl_cert_file = self.ssl_cert_file trusts.append(trust) return trusts
def getDomains(self, name=None, enabled=True): try: data = {"enabled": enabled} if name: data["name"] = name response = self.getResource("/domains", "GET", data=data) except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError("error on retrieving the domains list: %s" % response["error"]["message"]) domains = [] if response: domains_info = response["domains"] for info in domains_info: domain = Domain() domain.setId(info["id"]) domain.setName(info["name"]) domain.setEnabled(info["enabled"]) domains.append(domain) return domains
def getUser(self, id): try: response = self.getResource("users/%s" % id, "GET") except requests.exceptions.HTTPError as ex: response = ex.response.json() raise SynergyError( "error on retrieving the user info (id=%r): %s" % (id, response["error"]["message"])) user = None if response: info = response["user"] user = User() user.setId(info["id"]) user.setName(info["name"]) user.setEnabled(info["enabled"]) if "default_project_id" in info: user.setProjectId(info["default_project_id"]) elif "tenantId" in info: user.setProjectId(info["tenantId"]) return user
def _updateItemDB(self, item): if not item or not self.db_engine: return connection = self.db_engine.connect() trans = connection.begin() try: item.setLastUpdate(datetime.now()) QUERY = "update `%s`" % self.getName() QUERY += " set priority=%s, retry_count=%s, " \ "last_update=%s where id=%s" connection.execute(QUERY, [ item.getPriority(), item.getRetryCount(), item.getLastUpdate(), item.getId() ]) trans.commit() except SQLAlchemyError as ex: trans.rollback() raise SynergyError(ex.message) finally: connection.close()
def _insertItemDB(self, item): if not item or not self.db_engine: return QUERY = "insert into `%s` (user_id, prj_id, priority, " \ "data) values" % self.getName() QUERY += "(%s, %s, %s, %s)" connection = self.db_engine.connect() trans = connection.begin() try: result = connection.execute(QUERY, [ item.getUserId(), item.getProjectId(), item.getPriority(), json.dumps(item.getData()) ]) idRecord = result.lastrowid trans.commit() item.setId(idRecord) except SQLAlchemyError as ex: trans.SynergyError() raise SynergyError(ex.message) finally: connection.close()
def _buildFromDB(self): if not self.db_engine: return connection = self.db_engine.connect() try: QUERY = "select id, user_id, prj_id, priority, retry_count, " \ "creation_time, last_update from `%s`" % self.getName() result = connection.execute(QUERY) for row in result: item = QueueItem() item.setId(row[0]) item.setUserId(row[1]) item.setProjectId(row[2]) item.setPriority(row[3]) item.setRetryCount(row[4]) item.setCreationTime(row[5]) item.setLastUpdate(row[6]) self.restore(item) self._incSize(1) except SQLAlchemyError as ex: raise SynergyError(ex.message) finally: connection.close()
def execute(self, command, *args, **kargs): LOG.info("%r execute %r invoked!" % (self.name, command)) if command == "GET_TIME": return {"localtime": time.asctime(time.localtime(time.time()))} else: raise SynergyError("command %r not supported" % command)
def updateQuota(self, quota, is_class=False): if is_class: url = "os-quota-class-sets/%s" % quota.getId() qs = { "quota_class_set": { "cores": quota.getSize("vcpus"), "ram": quota.getSize("memory"), "instances": quota.getSize("instances") } } else: url = "os-quota-sets/%s" % quota.getId() qs = { "quota_set": { "force": True, "cores": quota.getSize("vcpus"), "ram": quota.getSize("memory"), "instances": quota.getSize("instances") } } try: self.getResource(url, "PUT", qs) except requests.exceptions.HTTPError as ex: raise SynergyError("error on updating the quota info (id=%r)" ": %s" % (id, ex.response.json()))
def execute(self, command, *args, **kargs): if command == "GET_PRIVATE_QUOTA": prj_id = kargs.get("id", None) prj_name = kargs.get("name", None) project = self.project_manager.getProject(prj_id, prj_name) if project: return project.getQuota() else: raise SynergyError("project not found!") if project: return project elif command == "GET_SHARED_QUOTA": return SharedQuota() else: raise SynergyError("command %r not supported!" % command)
def getHypervisor(self, id): data = {"os-stop": None} url = "os-hypervisors/%s" % id try: response_data = self.getResource(url, "GET", data) except requests.exceptions.HTTPError as ex: raise SynergyError("error on retrieving the hypervisor info (id=%r" "): %s" % (id, ex.response.json())) hypervisor = None if response_data: hypervisor_data = response_data["hypervisor"] hypervisor = Hypervisor() hypervisor.setId(hypervisor_data["id"]) hypervisor.setIP(hypervisor_data["host_ip"]) hypervisor.setName(hypervisor_data["hypervisor_hostname"]) hypervisor.setType(hypervisor_data["hypervisor_type"]) hypervisor.setState(hypervisor_data["state"]) hypervisor.setStatus(hypervisor_data["status"]) hypervisor.setWorkload(hypervisor_data["current_workload"]) hypervisor.setVMs(hypervisor_data["running_vms"]) hypervisor.setVCPUs(hypervisor_data["vcpus"]) hypervisor.setVCPUs(hypervisor_data["vcpus_used"], used=True) hypervisor.setMemory(hypervisor_data["memory_mb"]) hypervisor.setMemory(hypervisor_data["memory_mb_used"], used=True) hypervisor.setStorage(hypervisor_data["local_gb"]) hypervisor.setStorage(hypervisor_data["local_gb_used"], used=True) return hypervisor
def setQuotaTypeServer(self, server): if not server: return QUERY = "insert into nova.instance_metadata (created_at, `key`, " \ "`value`, instance_uuid) values (%s, 'quota', %s, %s)" connection = self.db_engine.connect() trans = connection.begin() quota_type = "private" if server.isEphemeral(): quota_type = "shared" try: connection.execute( QUERY, [server.getCreatedAt(), quota_type, server.getId()]) trans.commit() except SQLAlchemyError as ex: trans.rollback() raise SynergyError(ex.message) finally: connection.close()
def getServer(self, id, detail=False): try: response_data = self.getResource("servers/" + id, "GET") except requests.exceptions.HTTPError as ex: raise SynergyError("error on retrieving the server info (id=%r)" ": %s" % (id, ex.response.json())) server = None if response_data: server_data = response_data["server"] server = Server() server.setId(server_data["id"]) server.setName(server_data["name"]) server.setKeyName(server_data["key_name"]) server.setMetadata(server_data["metadata"]) server.setUserData( server_data.get("OS-EXT-SRV-ATTR:user_data", None)) server.setType() server.setState(server_data["OS-EXT-STS:vm_state"]) server.setUserId(server_data["user_id"]) server.setProjectId(server_data["tenant_id"]) server.setCreatedAt(server_data["created"]) server.setUpdatedAt(server_data.get("updated", None)) server.setLaunchedAt( server_data.get("OS-SRV-USG:launched_at", None)) server.setTerminatedAt( server_data.get("OS-SRV-USG:terminated_at", None)) if detail: server.setFlavor(self.getFlavor(server_data["flavor"]["id"])) return server
def getUsers(self, prj_id=None): users = [] if prj_id: try: data = {"scope.project.id": prj_id} response = self.getResource("role_assignments", "GET", data=data) user_list = {} for role in response["role_assignments"]: user_id = role["user"]["id"] if user_id in user_list: continue user = self.getUser(user_id) user.setProjectId(prj_id) user_list[user_id] = user users = user_list.values() except requests.exceptions.HTTPError as ex: response = ex.response.json() message = response["error"]["message"] raise SynergyError("error on retrieving the project's users " "(id=%r): %s" % (prj_id, message)) else: try: response = self.getResource("/users", "GET") for info in response["users"]: user = User() user.setId(info["id"]) user.setName(info["name"]) user.setProjectId(info["tenantId"]) user.setEnabled(info["enabled"]) users.append(user) except requests.exceptions.HTTPError as ex: response = ex.response.json() message = response["error"]["message"] raise SynergyError("error on retrieving the users list: %s" % message) return users
def createQueue(self, name, type): if name in self.queues: raise SynergyError("the queue %r already exists!" % name) queue = Queue(name, type, db_engine=self.db_engine) self.queues[name] = queue return queue
def _parseNumber(self, value, default=None): if not value: return default try: return int(value) except SynergyError: if default: return default raise SynergyError("%r is not a number!" % str(value))
def execute(self, command, *args, **kargs): if command == "GET_PROJECTS": return self.projects.values() prj_id = kargs.get("id", None) prj_name = kargs.get("name", None) project = self.getProject(prj_id, prj_name) if command == "GET_PROJECT": if project: return project else: raise SynergyError("project not found!") elif command == "ADD_PROJECT": if project: raise SynergyError( "the project id=%s name=%s already exists!" % (project.getId(), project.getName())) TTL = kargs.get("TTL", None) share = kargs.get("share", None) return self._addProject(prj_id, prj_name, TTL, share) elif command == "UPDATE_PROJECT": if not project: raise SynergyError("project not found!") TTL = kargs.get("TTL", None) share = kargs.get("share", None) return self._updateProject(project, TTL, share) elif command == "REMOVE_PROJECT": if not project: raise SynergyError("project not found!") self._removeProject(project) else: raise SynergyError("command %r not supported!" % command)
def deserialize(cls, entity): if "synergy_object" not in entity: raise SynergyError("it seems not a Synergy object!") synergy_object = entity["synergy_object"] if "namespace" not in synergy_object: raise SynergyError("synergy_object.namespace not defined!") if "name" not in synergy_object: raise SynergyError("synergy_object.name not defined!") if "version" not in synergy_object: raise SynergyError("synergy_object.version mismatch!") if synergy_object["version"] != cls.VERSION: raise SynergyError("synergy_object.version mis!") if synergy_object["namespace"] != "synergy": raise SynergyError( "unsupported object objtype='%s.%s" % (synergy_object["namespace"], synergy_object["name"])) objInstance = None try: objName = synergy_object["name"] objClass = utils.import_class(objName) objInstance = objClass() except Exception as ex: raise SynergyError("error on deserializing the object %r: %s" % (objName, ex)) del entity["synergy_object"] entity = utils.objectHookHandler(entity) for key, value in entity.items(): if isinstance(value, dict): if "synergy_object" in value: objInstance.set(key, SynergyObject.deserialize(value)) else: objInstance.set(key, value) elif isinstance(value, list): l = [] objInstance.set(key, l) for item in value: if isinstance(item, dict) and "synergy_object" in item: l.append(SynergyObject.deserialize(item)) else: l.append(item) else: objInstance.set(key, value) return objInstance
def _createTable(self): if not self.db_engine: return TABLE = """CREATE TABLE IF NOT EXISTS `%s` (`id` BIGINT NOT NULL \ AUTO_INCREMENT PRIMARY KEY, `priority` INT DEFAULT 0, user_id CHAR(40) \ NOT NULL, prj_id CHAR(40) NOT NULL, `retry_count` INT DEFAULT 0, \ `creation_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_update` \ TIMESTAMP NULL, `data` TEXT NOT NULL) ENGINE=InnoDB""" % self.getName() connection = self.db_engine.connect() try: connection.execute(TABLE) except SQLAlchemyError as ex: raise SynergyError(ex.message) except Exception as ex: raise SynergyError(ex.message) finally: connection.close()
def import_class(import_str): """Returns a class from a string including module and class.""" mod_str, _sep, class_str = import_str.rpartition('.') __import__(mod_str) try: return getattr(sys.modules[mod_str], class_str) except AttributeError: raise SynergyError( 'Class %s cannot be found (%s)' % (class_str, traceback.format_exception(*sys.exc_info())))
def getParameter(self, name, fallback=False): result = CONF.NovaManager.get(name, None) if result is not None: return result if fallback is True: raise SynergyError("No attribute %r found in [NovaManager] " "section of synergy.conf" % name) else: return None