Example #1
0
def download_manifest(appid):
    manifest = {}

    app = get_app_by_id(g.user.uid, appid)

    if not app:
        log('The appid %s does not exist' % appid)
        return simplejson.dumps(False)

    manifest['Services'] = []
    manifest['Application'] = app.name

    do_delete = False
    for service in Service.query.filter_by(application_id=appid):
        if service.type == "xtreemfs":
            do_delete = True

        svc_manifest = get_manifest_class(
            service.type)().get_service_manifest(service)

        manifest['Services'].append(svc_manifest)

    if do_delete:
        log("Deleting application %s, it contains an XtreemFS service" % appid)
        deleteapp(g.user.uid, appid)

    return simplejson.dumps(manifest)
Example #2
0
def download_manifest(appid):
    manifest = {}

    app = get_app_by_id(g.user.uid, appid)

    if not app:
        log('The appid %s does not exist' % appid)
        return simplejson.dumps(False)

    manifest['Services'] = []
    manifest['Application'] = app.name

    do_delete = False
    for service in Service.query.filter_by(application_id=appid):
        if service.type == "xtreemfs":
            do_delete = True

        svc_manifest = get_manifest_class(
                service.type)().get_service_manifest(service)

        manifest['Services'].append(svc_manifest)
    
    if do_delete:
        log("Deleting application %s, it contains an XtreemFS service" %
                appid)
        deleteapp(g.user.uid, appid)

    return simplejson.dumps(manifest)
Example #3
0
        def decorated(*args, **kwargs):
            g.cert = {}

            if os.environ.get('DIRECTOR_TESTING'):
                # No SSL certificate check if we are testing. Trust what the
                # client is sending.
                g.cert['UID'] = request.values.get('uid')
                g.cert['role'] = request.values.get('role')
                # g.cert['serviceLocator'] = request.values.get('sid')
                g.cert['serviceLocator'] = request.values.get('aid')
            else:
                cert = request.environ['SSL_CLIENT_CERT']
                for key in 'serviceLocator', 'UID', 'role':
                    g.cert[key] = https.x509.get_x509_dn_field(cert, key)

            try:
                uid = int(g.cert['UID'])
            except (AttributeError, ValueError, TypeError):
                error_msg = 'cert_required: client certificate does NOT provide UID'
                log(error_msg)
                return make_response(error_msg, 401)

            # Getting user data from DB
            g.user = User.query.get(uid)
            if not g.user:
                # authentication failed
                return build_response(simplejson.dumps(False))

            if self.role == 'manager':
                # manager cert required
                try:
                    service_locator = int(g.cert['serviceLocator'])
                except (AttributeError, ValueError):
                    error_msg = 'cert_required: client certificate does NOT provide serviceLocator'
                    log(error_msg)
                    # Return HTTP_UNAUTHORIZED
                    return make_response(error_msg, 401)

                # check if the service is actually owned by the user
                # from cpsdirector.service import get_service
                # g.service = get_service(uid, service_locator)
                # if not g.service:
                #     return build_response(simplejson.dumps(False))

                from cpsdirector.application import get_app_by_id
                g.application = get_app_by_id(uid, service_locator)
                if not g.application:
                    return build_response(simplejson.dumps(False))

                log('cert_required: valid certificate (user %s, application %s)' % (uid, service_locator))

            return fn(*args, **kwargs)
Example #4
0
def upload_manifest():
    json = request.values.get('manifest')
    if not json:
        msg = '"manifest" is a required argument'
        log_error(msg)
        return build_response(jsonify(error_response(msg)))

    log("User '%s' has uploaded the following manifest: %s" % (g.user.username, json))

    if not check_manifest(json):
        msg = 'The uploded manifest is not valid'
        return build_response(jsonify(error_response(msg)))

    try:
        parse = simplejson.loads(json)
    except:
        msg = 'Error parsing json'
        log_error(msg)
        return build_response(jsonify(error_response(msg)))

    msg, appid = create_manifest_app(parse)
    if msg != 'ok':
        log_error(msg)
        return build_response(jsonify(error_response(msg)))

    if not parse.get('Services'):
        log('Manifest: Application not started, as no services are defined.')
        return build_response(jsonify({}))

    app = get_app_by_id(g.user.uid, appid)
    app.status = Application.A_PROLOGUE
    db.session.commit()

    cloud = request.values.get('cloud')
    if not cloud or cloud == 'None':
        cloud = 'default'

    if request.values.get('thread'):
        log('Starting a new process for the manifest')
        p = Process(target=start_manifest_app, args=(parse, appid, cloud))
        p.start()

        log('Process started, now return')
        return build_response(jsonify({ 'aid': appid }))
    else:
        msg = start_manifest_app(parse, appid, cloud)
        if msg != 'ok':
            log_error(msg)
            return build_response(jsonify(error_response(msg)))

        return build_response(jsonify({ 'aid': appid }))
Example #5
0
def _start(servicetype, cloudname, appid):
    log('User %s creating a new %s service inside application %s' % (
	    g.user.username, servicetype, appid))

    # Check if we got a valid service type
    if servicetype not in valid_services:
        error_msg = 'Unknown service type: %s' % servicetype
        log(error_msg)
        return build_response(jsonify({ 'error': True,
                                        'msg': error_msg }))

    app = get_app_by_id(g.user.uid, appid)
    if not app:
        return build_response(jsonify({ 'error': True,
		                        'msg': "Application not found" }))

    # Do we have to assign a VPN subnet to this service?
    vpn = app.get_available_vpn_subnet()

    # Default name
    if servicetype == 'galera':
        defaultname = 'New MySQL service';
    else:
        defaultname = "New %s service" % servicetype

    # New service with default name, proper servicetype and user relationship
    s = Service(name=defaultname, type=servicetype,
        user=g.user, application=app, subnet=vpn)

    db.session.add(s)
    # flush() is needed to get auto-incremented sid
    db.session.flush()

    try:
        s.manager, s.manager_port, s.vmid, s.cloud = manager_controller.start(
            servicetype, s.sid, g.user.uid, cloudname, appid, vpn)
    except Exception, err:
        try:
            db.session.delete(s)
            db.session.commit()
        except InvalidRequestError:
            db.session.rollback()
        exc_type, exc_value, exc_traceback = sys.exc_info()
        lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
        log(''.join('!! ' + line for line in lines))
        error_msg = 'Error upon service creation: %s' % err
        log(error_msg)
        return build_response(jsonify({ 'error': True, 'msg': error_msg }))
Example #6
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)
Example #7
0
def _start(servicetype, cloudname, appid):
    log('User %s creating a new %s service inside application %s' %
        (g.user.username, servicetype, appid))

    # Check if we got a valid service type
    if servicetype not in valid_services:
        error_msg = 'Unknown service type: %s' % servicetype
        log(error_msg)
        return build_response(jsonify({'error': True, 'msg': error_msg}))

    app = get_app_by_id(g.user.uid, appid)
    if not app:
        return build_response(
            jsonify({
                'error': True,
                'msg': "Application not found"
            }))

    # Do we have to assign a VPN subnet to this service?
    vpn = app.get_available_vpn_subnet()

    # New service with default name, proper servicetype and user relationship
    s = Service(name="New %s service" % servicetype,
                type=servicetype,
                user=g.user,
                application=app,
                subnet=vpn)

    db.session.add(s)
    # flush() is needed to get auto-incremented sid
    db.session.flush()

    try:
        s.manager, s.vmid, s.cloud = manager_controller.start(
            servicetype, s.sid, g.user.uid, cloudname, appid, vpn)
    except Exception, err:
        try:
            db.session.delete(s)
            db.session.commit()
        except InvalidRequestError:
            db.session.rollback()
        exc_type, exc_value, exc_traceback = sys.exc_info()
        lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
        log(''.join('!! ' + line for line in lines))
        error_msg = 'Error upon service creation: %s %s' % (type(err), err)
        log(error_msg)
        return build_response(jsonify({'error': True, 'msg': error_msg}))
Example #8
0
def _create_nodes(kwargs):

    role = kwargs.pop('role')
    nodes_info = kwargs.pop('nodes_info')
    clouds = _get_cloud_list(nodes_info)

    app_id = kwargs.pop('app_id')
    user_id = kwargs.pop('user_id')
    nodes = None
    service_id = 0

    if role == 'manager':
        vpn = kwargs.pop('vpn')
        controller = ManagerController(user_id, app_id, vpn)
        controller.generate_context(clouds)
        nodes = controller.create_nodes(nodes_info, clouds)

        if not kwargs.pop('ignore_status'):
            from cpsdirector.application import Application, get_app_by_id
            application = get_app_by_id(user_id, app_id)
            application.status = Application.A_RUNNING
    else:
        service_id = kwargs.pop('service_id')
        service_type = kwargs.pop('service_type')
        manager_ip = kwargs.pop('manager_ip')
        context = kwargs.pop('context')
        startup_script = kwargs.pop('startup_script')

        log('Create node called for service type: %s' % service_type)

        controller = AgentController(user_id, app_id, service_id, service_type, manager_ip)
        controller.generate_context(clouds, context, startup_script)
        nodes = controller.create_nodes(nodes_info, clouds)

    if nodes:
        for node in nodes:
            resource = Resource(vmid=node.vmid, ip=node.ip, app_id=app_id, service_id=service_id, role=role, cloud=node.cloud_name)
            db.session.add(resource)

        db.session.flush()
        db.session.commit()

        Credit().check_credits()

    return nodes
Example #9
0
def download_manifest(appid):
    manifest = {}

    app = get_app_by_id(g.user.uid, appid)

    if not app:
        log('The appid %s does not exist' % appid)
        return simplejson.dumps(False)

    manifest['Services'] = []
    manifest['Application'] = app.name

    for service in Service.query.filter_by(application_id=appid):
        svc_manifest = get_manifest_class(
                service.type)().get_service_manifest(service)

        manifest['Services'].append(svc_manifest)

    return simplejson.dumps(manifest)
Example #10
0
def download_manifest(appid):
    manifest = {}

    app = get_app_by_id(g.user.uid, appid)

    if not app:
        log('The appid %s does not exist' % appid)
        return simplejson.dumps(False)

    manifest['Services'] = []
    manifest['Application'] = app.name

    for service in Service.query.filter_by(application_id=appid):
        tmp = {}
        tmp['Type'] = service.type
        tmp['ServiceName'] = service.name
        tmp['Cloud'] = service.cloud
        manifest['Services'].append(tmp)

    return simplejson.dumps(manifest)
Example #11
0
def download_manifest(appid):
    manifest = {}

    app = get_app_by_id(g.user.uid, appid)

    if not app:
        log('The appid %s does not exist' % appid)
        return simplejson.dumps(False)

    manifest['Services'] = []
    manifest['Application'] = app.name

    for service in Service.query.filter_by(application_id=appid):
        tmp = {}
        tmp['Type'] = service.type
        tmp['ServiceName'] = service.name
        tmp['Cloud'] = service.cloud
        manifest['Services'].append(tmp)

    return simplejson.dumps(manifest)
Example #12
0
def start_manifest_app(parse, appid, cloud='default'):

    res = startapp(g.user.uid, appid, cloud, new_thread=False, ignore_status=True)
    # res = startapp(g.user.uid, appid, cloud, ignore_status=True)
    if 'error' in res:
        return res['error']

    app = get_app_by_id(g.user.uid, appid)

    # #FIXME: add a timeout here
    # while app.status != Application.A_RUNNING:
    #     # log('application is in status:%s, manager:%s' % (app.status, app.manager))
    #     time.sleep(8)
    #     app = get_app_by_id(g.user.uid, appid)
    #     db.session.refresh(app)
    #     # app = get_app_by_id(g.user.uid, appid)

    log('Now start adding services for application %s' % appid)
    app.status = Application.A_ADAPTING
    db.session.commit()

    for service in parse.get('Services'):
        try:
            cls = get_manifest_class(service.get('Type'))
        except Exception:
            return 'Service %s does not exists' % service.get('Type')

        msg = cls().start(service, appid, cloud)
        if msg is not 'ok':
            log_error('Error starting %s service -> %s' % (service, msg))
            return msg

    log('All services of application %s are now running' % appid)
    app.status = Application.A_RUNNING
    db.session.commit()

    return 'ok'
Example #13
0
def _add(service_type, app_id):
    log("User '%s' is attempting to add a new %s service to application %s"
        % (g.user.username, service_type, app_id))

    # Use default application id if no appid was specified
    if not app_id:
        app = get_default_app(g.user.uid)
        if not app:
            msg = "No existing applications"
            log_error(msg)
            return error_response(msg)
        else:
            app_id = app.aid
    else:
        app = get_app_by_id(g.user.uid, app_id)

    # Check if we got a valid service type
    if service_type not in valid_services:
        msg = "Unknown service type '%s'" % service_type
        log_error(msg)
        return error_response(msg)

    data = { 'service_type': service_type }
    res  = callmanager(app_id, 0, "add_service", True, data)

    if 'service_id' in res:
        sid = res['service_id']
        s = Service(sid=sid, name="New %s service" % service_type, type=service_type,
            user=g.user, application=app, manager=app.to_dict()['manager'])
        db.session.add(s)
        db.session.commit()

        log('Service created successfully')
        return s.to_dict()

    return res