Exemplo n.º 1
0
    def callmanager(self, service_id, method, post, data, files=[]):
        """Call the manager API.

        'service_id': an integer holding the service id of the manager.
        'method': a string representing the API method name.
        'post': boolean value. True for POST method, false for GET.
        'data': a dictionary representing the data to be sent to the director.
        'files': sequence of (name, filename, value) tuples for data to be uploaded as files.

        callmanager loads the manager JSON response and returns it as a Python
        object.
        """
        service = self.service_dict(service_id)

        # File upload
        if files:
            res = client.https_post(service['manager'], 443, '/', data, files)
        # POST
        elif post:
            res = client.jsonrpc_post(service['manager'], 443, '/', method, data)
        # GET
        else:
            res = client.jsonrpc_get(service['manager'], 443, '/', method, data)

        if res[0] == 200:
            try:
                data = simplejson.loads(res[1])
            except simplejson.decoder.JSONDecodeError:
                # Not JSON, simply return what we got
                return res[1]

            return data.get('result', data)

        raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % (
            method, service['manager'], res[1], data)
Exemplo n.º 2
0
def callmanager(app_id, service_id, method, post, data, files=[]):
    """Call the manager API.

    'service_id': an integer holding the service id of the manager.
    'method': a string representing the API method name.
    'post': boolean value. True for POST method, false for GET.
    'data': a dictionary representing the data to be sent to the director.
    'files': sequence of (name, filename, value) tuples for data to be uploaded as files.

    callmanager loads the manager JSON response and returns it as a Python
    object.
    """
    client.conpaas_init_ssl_ctx('/etc/cpsdirector/certs', 'director')

    application = get_app_by_id(g.user.uid, app_id)

    if application is None:
        msg = "Application %s not found." % app_id
        log_error(msg)
        return error_response(msg)
    elif application.to_dict()['manager'] is None:
        msg = "Application %s has not started. Try to start it first." % app_id
        log_error(msg)
        return error_response(msg)

    application = application.to_dict()
    # File upload
    if files:
        data['service_id'] = service_id
        res = client.https_post(application['manager'], 443, '/', data, files)
    # POST
    elif post:
        res = client.jsonrpc_post(application['manager'], 443, '/', method, service_id, data)
    # GET
    else:
        res = client.jsonrpc_get(application['manager'], 443, '/', method, service_id, data)

    if res[0] == 200:
        try:
            data = simplejson.loads(res[1])
        except simplejson.decoder.JSONDecodeError:
            # Not JSON, simply return what we got
            return res[1]

        return data.get('result', data)

    raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % (method, application['manager'], res[1], data)
Exemplo n.º 3
0
def callmanager(service_id, method, post, data, files=[]):
    """Call the manager API.

    'service_id': an integer holding the service id of the manager.
    'method': a string representing the API method name.
    'post': boolean value. True for POST method, false for GET.
    'data': a dictionary representing the data to be sent to the director.
    'files': sequence of (name, filename, value) tuples for data to be uploaded as files.

    callmanager loads the manager JSON response and returns it as a Python
    object.
    """
    service = get_service(g.user.uid, service_id)

    client.conpaas_init_ssl_ctx('/etc/cpsdirector/certs', 'director')

    # File upload
    if files:
        res = client.https_post(service.manager, 443, '/', data, files)
    # POST
    elif post:
        res = client.jsonrpc_post(service.manager, 443, '/', method, data)
    # GET
    else:
        #res = client.jsonrpc_get(service.manager, 443, '/', method, data)
        if service.manager_port:
            node = service.manager_port.split(":")
            if len(node) == 2:
                _ip, _port = node
            else:
                _ip, _port = (service.manager, 443)
        res = client.jsonrpc_get(_ip, int(_port), '/', method, data)

    if res[0] == 200:
        try:
            data = simplejson.loads(res[1])
        except simplejson.decoder.JSONDecodeError:
            # Not JSON, simply return what we got
            return res[1]

        return data.get('result', data)

    raise Exception, "Call to method %s on %s failed: %s.\nParams = %s" % (
        method, service.manager, res[1], data)
Exemplo n.º 4
0
    def call_director(self, method, post, data=None, use_certs=True):
        """Call the director API.
        Loads the director JSON response and returns it as a Python object.
        If the returned data can not be decoded it is returned as it is.

        'method': a string representing the API method name.
        'post': boolean value. True for POST method, false for GET.
        'data': a dictionary representing the data to be sent to the director.

        TODO: use HTTPMethod.x instead of bool for post parameter...
        """
        if self.director_url is None:
            raise Exception("Cannot call the ConPaaS director:" " the director URL address is not specified.")

        if data is None:
            data = {}

        if not "username" in data:
            data["username"] = self.username

        if data["username"] is None:
            raise Exception("Cannot call the ConPaaS director:" " user name is not specified.")

        if use_certs:
            # If certificates are used, the ssl context should already have
            # been initialized with the user's certificates in __init__
            if not client.is_ssl_ctx_initialized():
                raise Exception(
                    "Cannot call the ConPaaS director: "
                    "user certificates are not present.\n"
                    "Try to run 'cps-user get_certificate' "
                    "first."
                )

            if self.debug:
                self.logger.debug("User certificates are present and will be used.")
        else:
            # If not, we need to send the user's password and initialize the
            # ssl context with one that does not use certificates
            if not "password" in data:
                if self.password is None:
                    data["password"] = self._get_password()
                else:
                    data["password"] = self.password

            client.conpaas_init_ssl_ctx_no_certs()

            if self.debug:
                self.logger.debug("User certificates will NOT be used.")

        url = "%s/%s" % (self.director_url, method)

        if self.debug:
            if "password" in data:
                data_log = dict(data)
                # hiding password from log
                if data_log["password"] == "":
                    data_log["password"] = "******"
                else:
                    data_log["password"] = "******"
            else:
                data_log = data
            self.logger.info("Requesting '%s' with data %s." % (url, data_log))

        parsed_url = urlparse.urlparse(self.director_url)
        try:
            if post:
                status, body = client.https_post(parsed_url.hostname, parsed_url.port or 443, url, data)
            else:
                status, body = client.https_get(parsed_url.hostname, parsed_url.port or 443, url, data)
        except Exception as ex:
            if "certificate verify failed" in str(ex):
                raise Exception(
                    "The ConPaaS director's SSL certificate "
                    "failed verification.\n"
                    "You may be the victim of a man-in-the-middle "
                    "attack or, if you recently changed the "
                    "ConPaaS deployment, you need to run "
                    "'cps-user get_certificate' first."
                )
            if self.debug:
                traceback.print_exc()
            raise Exception("Cannot contact the director at URL '%s': %s" % (url, ex))

        if status != 200:
            raise Exception(
                "Call to method '%s' on '%s' failed: HTTP status %s.\n" "Params = %s" % (method, url, status, data)
            )

        try:
            res = simplejson.loads(body)
        except simplejson.decoder.JSONDecodeError:
            # Not JSON, simply return what we got
            if self.debug:
                self.logger.info("Call succeeded, result is not json.")
            return body

        if type(res) is dict and "error" in res:
            if self.debug:
                self.logger.info("Call succeeded, result contains an error")
            raise Exception(res["error"])

        self.logger.info("Call succeeded, result is: %s" % res)
        return res
Exemplo n.º 5
0
    def call_manager(self, app_id, service_id, method, post, data=None, files=None):
        """Call the manager API.
        Loads the manager JSON response and returns it as a Python object.

        'service_id': an integer holding the service id of the manager.
        'method': a string representing the API method name.
        'post': boolean value. True for POST method, false for GET.
        'data': a dictionary representing the data to be sent to the director.
        'files': sequence of (name, filename, value) tuples for data to be
                 uploaded as files.
        """

        application = self.application_dict(app_id)

        if application["manager"] is None:
            raise Exception("Application %s has not started. Try to start it first." % app_id)

        if data is None:
            data = {}
        if files is None:
            files = []

        url = "https://%s/" % application["manager"]

        # Certificates are always used, the ssl context should already have
        # been initialized with the user's certificates in __init__
        if not client.is_ssl_ctx_initialized():
            raise Exception(
                "Cannot call the manager: "
                "user certificates are not present.\n"
                "Try to run 'cps-user get_certificate' "
                "first."
            )
        if self.debug:
            self.logger.debug("User certificates are present and will be used.")
            self.logger.info(
                "Requesting '%s' with aid %s, sid %s, method '%s', "
                "data %s and %s files." % (url, app_id, service_id, method, data, len(files))
            )

        try:
            # File upload
            if files:
                status, body = client.https_post(application["manager"], 443, "/", data, files)
            # POST
            elif post:
                status, body = client.jsonrpc_post(application["manager"], 443, "/", method, service_id, data)
            # GET
            else:
                status, body = client.jsonrpc_get(application["manager"], 443, "/", method, service_id, data)
        except Exception as ex:
            if "certificate verify failed" in str(ex):
                raise Exception(
                    "The ConPaaS manager's SSL certificate "
                    "failed verification.\n"
                    "You may be the victim of a man-in-the-middle "
                    "attack or, if you recently changed the "
                    "ConPaaS deployment, you need to run "
                    "'cps-user get_certificate' first."
                )
            if self.debug:
                traceback.print_exc()
            raise Exception("Cannot contact the manager at URL '%s': %s" % (url, ex))

        if status != 200:
            raise Exception(
                "Call to method '%s' on '%s' failed: HTTP status %s.\n"
                "Params = %s" % (method, application["manager"], status, data)
            )

        try:
            data = simplejson.loads(body)
        except simplejson.decoder.JSONDecodeError:
            # Not JSON, simply return what we got
            if self.debug:
                self.logger.info("Call succeeded, result is not json.")
            return body

        res = data.get("result", data)
        if type(res) is dict and "error" in res:
            if self.debug:
                self.logger.info("Call succeeded, result contains an error")
            raise Exception(res["error"])

        self.logger.info("Call succeeded, result is: %s" % res)
        return res