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")
Beispiel #6
0
    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()
Beispiel #17
0
    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
Beispiel #25
0
    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))
Beispiel #26
0
    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)
Beispiel #27
0
    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()
Beispiel #29
0
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