예제 #1
0
def shell_command(request):
    """Sends a shell command to a machine over ssh, using fabric.

    .. note:: Used for uptime only.

    """
    try:
        conn = connect(request)
    except:
        return Response("Backend not found", 404)

    machine_id = request.matchdict["machine"]
    backend_id = request.matchdict["backend"]
    host = request.params.get("host", None)
    ssh_user = request.params.get("ssh_user", None)
    command = request.params.get("command", None)

    if not ssh_user or ssh_user == "undefined":
        ssh_user = "******"

    try:
        keypairs = request.environ["beaker.session"]["keypairs"]
    except:
        keypairs = request.registry.settings.get("keypairs", {})

    keypair = get_keypair(keypairs, backend_id, machine_id)

    if keypair:
        private_key = keypair["private"]
        public_key = keypair["public"]
    else:
        private_key = public_key = None

    ret = run_command(conn, machine_id, host, ssh_user, private_key, command)
    return ret
예제 #2
0
파일: views.py 프로젝트: michailb/mist.io
def shell_command(request):
    """Sends a shell command to a machine over ssh, using fabric.

    .. note:: Used for uptime only.

    """
    try:
        conn = connect(request)
    except:
        return Response('Backend not found', 404)

    machine_id = request.matchdict['machine']
    backend_id = request.matchdict['backend']
    host = request.params.get('host', None)
    ssh_user = request.params.get('ssh_user', None)
    command = request.params.get('command', None)

    if not ssh_user or ssh_user == 'undefined':
        ssh_user = '******'

    try:
        keypairs = request.environ['beaker.session']['keypairs']
    except:
        keypairs = request.registry.settings.get('keypairs', {})

    keypair = get_keypair(keypairs, backend_id, machine_id)

    if keypair:
        private_key = keypair['private']
        public_key = keypair['public']
    else:
        private_key = public_key = None

    ret = run_command(conn, machine_id, host, ssh_user, private_key, command)
    return ret
예제 #3
0
def shell_command(request):
    """Send a shell command to a machine over ssh, using fabric."""
    try:
        conn = connect(request)
    except:
        return Response('Backend not found', 404)

    machine_id = request.matchdict['machine']
    backend_id = request.matchdict['backend']
    host = request.params.get('host', None)
    ssh_user = request.params.get('ssh_user', None)
    command = request.params.get('command', None)

    if not ssh_user or ssh_user == 'undefined':
        ssh_user = '******'

    try:
        keypairs = request.environ['beaker.session']['keypairs']
    except:
        keypairs = request.registry.settings.get('keypairs', {})

    keypair = get_keypair(keypairs, backend_id, machine_id)

    if keypair:
        private_key = keypair['private']
        public_key = keypair['public']
    else:
        private_key = public_key = None

    return run_command(conn, machine_id, host, ssh_user, private_key, command)
예제 #4
0
    def __call__(self, environ, start_response):
        request = Request(environ)

        if request.path.endswith('shell') and request.method == 'GET':
            try:
                backend = self.app.routes_mapper(request)['match']['backend']
                machine = self.app.routes_mapper(request)['match']['machine']
                host = request.params.get('host', None)
                ssh_user = request.params.get('ssh_user', None)
                command = request.params.get('command', None)
                request.registry = self.app.registry

                if not ssh_user or ssh_user == 'undefined':
                    ssh_user = '******'

                try:
                    keypairs = environ['beaker.session']['keypairs']
                except:
                    keypairs = request.registry.settings.get('keypairs', {})

                keypair = get_keypair(keypairs, backend, machine)

                if keypair:
                    private_key = keypair['private']
                else:
                    private_key = None

                conn = connect(request, backend)
                if conn:
                    return self.stream_command(conn, machine, host, ssh_user,
                                               private_key, command,
                                               start_response)
                else:
                    raise
            except:
                # leave error handling up to the app
                return self.app(environ, start_response)
        else:
            return self.app(environ, start_response)
예제 #5
0
    def __call__(self, environ, start_response):
        request = Request(environ)
                                    
        if request.path.endswith('shell') and request.method == 'GET':
            try:
                backend = self.app.routes_mapper(request)['match']['backend']
                machine = self.app.routes_mapper(request)['match']['machine']
                host = request.params.get('host', None)
                ssh_user = request.params.get('ssh_user', None)
                command = request.params.get('command', None)
                request.registry = self.app.registry

                if not ssh_user or ssh_user == 'undefined':
                    ssh_user = '******'

                try:
                    keypairs = environ['beaker.session']['keypairs']
                except:
                    keypairs = request.registry.settings.get('keypairs', {})

                keypair = get_keypair(keypairs, backend, machine)
              
                if keypair:
                    private_key = keypair['private']
                else:
                    private_key = None

                conn = connect(request, backend)
                if conn:
                    return self.stream_command(conn, machine, host, ssh_user, 
                                               private_key, command, 
                                               start_response)
                else:
                    raise
            except:
                # leave error handling up to the app
                return self.app(environ, start_response)
        else:
            return self.app(environ, start_response)
예제 #6
0
def create_machine(request):
    """Creates a new virtual machine on the specified backend.

    If the backend is Rackspace it attempts to deploy the node with an ssh key
    provided in config. the method used is the only one working in the old
    Rackspace backend. create_node(), from libcloud.compute.base, with 'auth'
    kwarg doesn't do the trick. Didn't test if you can upload some ssh related
    files using the 'ex_files' kwarg from openstack 1.0 driver.

    In Linode creation is a bit different. There you can pass the key file
    directly during creation. The Linode API also requires to set a disk size
    and doesn't get it from size.id. So, send size.disk from the client and
    use it in all cases just to avoid provider checking. Finally, Linode API
    does not support association between a machine and the image it came from.
    We could set this, at least for machines created through mist.io in
    ex_comment, lroot or lconfig. lroot seems more appropriate. However,
    liblcoud doesn't support linode.config.list at the moment, so no way to
    get them. Also, it will create inconsistencies for machines created
    through mist.io and those from the Linode interface.

    """
    try:
        conn = connect(request)
    except:
        return Response("Backend not found", 404)

    backend_id = request.matchdict["backend"]

    try:
        key_id = request.json_body["key"]
    except:
        key_id = None

    try:
        keypairs = request.environ["beaker.session"]["keypairs"]
    except:
        keypairs = request.registry.settings.get("keypairs", {})

    if key_id:
        keypair = get_keypair_by_name(keypairs, key_id)
    else:
        keypair = get_keypair(keypairs)

    if keypair:
        private_key = keypair["private"]
        public_key = keypair["public"]
    else:
        private_key = public_key = None

    try:
        machine_name = request.json_body["name"]
        location_id = request.json_body["location"]
        image_id = request.json_body["image"]
        size_id = request.json_body["size"]
        # deploy_script received as unicode, but ScriptDeployment wants str
        script = str(request.json_body.get("script", ""))
        # these are required only for Linode, passing them anyway
        image_extra = request.json_body["image_extra"]
        disk = request.json_body["disk"]
    except Exception as e:
        return Response("Invalid payload", 400)

    size = NodeSize(size_id, name="", ram="", disk=disk, bandwidth="", price="", driver=conn)
    image = NodeImage(image_id, name="", extra=image_extra, driver=conn)

    if conn.type in EC2_PROVIDERS:
        locations = conn.list_locations()
        for loc in locations:
            if loc.id == location_id:
                location = loc
                break
    else:
        location = NodeLocation(location_id, name="", country="", driver=conn)

    if conn.type in [Provider.RACKSPACE_FIRST_GEN, Provider.RACKSPACE] and public_key:
        key = SSHKeyDeployment(str(public_key))
        deploy_script = ScriptDeployment(script)
        msd = MultiStepDeployment([key, deploy_script])
        try:
            node = conn.deploy_node(name=machine_name, image=image, size=size, location=location, deploy=msd)
            associate_key(request, key_id, backend_id, node.id, deploy=False)
        except Exception as e:
            return Response("Failed to create machine in Rackspace: %s" % e, 500)
    elif conn.type in EC2_PROVIDERS and public_key and private_key:
        imported_key = import_key(conn, public_key, key_id)
        created_security_group = create_security_group(conn, EC2_SECURITYGROUP)
        deploy_script = ScriptDeployment(script)

        (tmp_key, tmp_key_path) = tempfile.mkstemp()
        key_fd = os.fdopen(tmp_key, "w+b")
        key_fd.write(private_key)
        key_fd.close()
        # deploy_node wants path for ssh private key
        if imported_key and created_security_group:
            try:
                node = conn.deploy_node(
                    name=machine_name,
                    image=image,
                    size=size,
                    deploy=deploy_script,
                    location=location,
                    ssh_key=tmp_key_path,
                    ssh_alternate_usernames=["ec2-user", "ubuntu"],
                    max_tries=1,
                    ex_keyname=key_id,
                    ex_securitygroup=EC2_SECURITYGROUP["name"],
                )
                associate_key(request, key_id, backend_id, node.id, deploy=False)
            except Exception as e:
                return Response("Failed to create machine in EC2: %s" % e, 500)
        # remove temp file with private key
        try:
            os.remove(tmp_key_path)
        except:
            pass
    elif conn.type is Provider.LINODE and public_key and private_key:
        auth = NodeAuthSSHKey(public_key)

        (tmp_key, tmp_key_path) = tempfile.mkstemp()
        key_fd = os.fdopen(tmp_key, "w+b")
        key_fd.write(private_key)
        key_fd.close()

        deploy_script = ScriptDeployment(script)
        try:
            node = conn.deploy_node(
                name=machine_name,
                image=image,
                size=size,
                deploy=deploy_script,
                location=location,
                auth=auth,
                ssh_key=tmp_key_path,
            )
            associate_key(request, key_id, backend_id, node.id, deploy=False)
        except Exception as e:
            return Response("Failed to create machine in Linode: %s" % e, 500)
        # remove temp file with private key
        try:
            os.remove(tmp_key_path)
        except:
            pass
    else:
        return Response("Cannot create a machine without a keypair", 400)

    return {
        "id": node.id,
        "name": node.name,
        "extra": node.extra,
        "public_ips": node.public_ips,
        "private_ips": node.private_ips,
    }
예제 #7
0
def create_machine(request):
    """Creates a new virtual machine on the specified backend.

    If the backend is Rackspace it attempts to deploy the node with an ssh key
    provided in config. the method used is the only one working in the old
    Rackspace backend. create_node(), from libcloud.compute.base, with 'auth'
    kwarg doesn't do the trick. Didn't test if you can upload some ssh related
    files using the 'ex_files' kwarg from openstack 1.0 driver.

    In Linode creation is a bit different. There you can pass the key file
    directly during creation. The Linode API also requires to set a disk size
    and doesn't get it from size.id. So, send size.disk from the client and
    use it in all cases just to avoid provider checking. Finally, Linode API
    does not support association between a machine and the image it came from.
    We could set this, at least for machines created through mist.io in
    ex_comment, lroot or lconfig. lroot seems more appropriate. However,
    liblcoud doesn't support linode.config.list at the moment, so no way to
    get them. Also, it will create inconsistencies for machines created
    through mist.io and those from the Linode interface.
    """

    try:
        conn = connect(request)
    except:
        return Response('Backend not found', 404)

    backend_id = request.matchdict['backend']

    try:
        key_name = request.json_body['key']
    except:
        key_name = None
    
    try:
        keypairs = request.environ['beaker.session']['keypairs']
    except:
        keypairs = request.registry.settings.get('keypairs', {})

    if key_name:
        keypair = get_keypair_by_name(keypairs, key_name)
    else:
        keypair = get_keypair(keypairs)      

    if keypair:
        private_key = keypair['private']
        public_key = keypair['public']
    else:
        private_key = public_key = None

    try:
        machine_name = request.json_body['name']
        location_id = request.json_body['location']
        image_id = request.json_body['image']
        size_id = request.json_body['size']
        #deploy_script received as unicode, but ScriptDeployment wants str
        script = str(request.json_body.get('script', ''))
        # these are required only for Linode, passing them anyway
        image_extra = request.json_body['image_extra']
        disk = request.json_body['disk']
    except Exception as e:
        return Response('Invalid payload', 400)

    size = NodeSize(size_id, name='', ram='', disk=disk, bandwidth='',
                    price='', driver=conn)
    image = NodeImage(image_id, name='', extra=image_extra, driver=conn)

    if conn.type in EC2_PROVIDERS:
        locations = conn.list_locations()
        for loc in locations:
            if loc.id == location_id:
                location = loc
                break
    else:
        location = NodeLocation(location_id, name='', country='', driver=conn)
    
    if conn.type in [Provider.RACKSPACE_FIRST_GEN, Provider.RACKSPACE] and\
    public_key:
        key = SSHKeyDeployment(str(public_key))
        deploy_script = ScriptDeployment(script)
        msd = MultiStepDeployment([key, deploy_script])        
        try:
            node = conn.deploy_node(name=machine_name,
                             image=image,
                             size=size,
                             location=location,
                             deploy=msd)
            if keypair:
                machines = keypair.get('machines', None)
                if machines and len(machines):
                    keypair['machines'].append([backend_id, node.id])
                else:
                    keypair['machines'] = [[backend_id, node.id],]
                save_keypairs(request, keypair)
        except Exception as e:
            return Response('Something went wrong with node creation in RackSpace: %s' % e, 500)
    elif conn.type in EC2_PROVIDERS and public_key:
        imported_key = import_key(conn, public_key, key_name)
        created_security_group = create_security_group(conn, EC2_SECURITYGROUP)
        deploy_script = ScriptDeployment(script)

        (tmp_key, tmp_key_path) = tempfile.mkstemp()
        key_fd = os.fdopen(tmp_key, 'w+b')
        key_fd.write(private_key)
        key_fd.close()
        #deploy_node wants path for ssh private key
        if imported_key and created_security_group:
            try:
                node = conn.deploy_node(name=machine_name,
                                 image=image,
                                 size=size,
                                 deploy=deploy_script,
                                 location=location,
                                 ssh_key=tmp_key_path,
                                 ex_keyname=key_name,
                                 ex_securitygroup=EC2_SECURITYGROUP['name'])

                if keypair:
                    machines = keypair.get('machines', None)
                    if machines and len(machines):
                        keypair['machines'].append([backend_id, node.id])
                    else:
                        keypair['machines'] = [[backend_id, node.id],]
                    save_keypairs(request, keypair)
            except Exception as e:
                return Response('Something went wrong with node creation in EC2: %s' % e, 500)
        #remove temp file with private key
        try:
            os.remove(tmp_key_path)
        except:
            pass
    elif conn.type is Provider.LINODE and public_key:
        auth = NodeAuthSSHKey(public_key)
        deploy_script = ScriptDeployment(script)
        try:
            node = conn.create_node(name=machine_name,
                             image=image,
                             size=size,
                             deploy=deploy_script,
                             location=location,
                             auth=auth)
            if keypair:
                machines = keypair.get('machines', None)
                if machines and len(machines):
                    keypair['machines'].append([backend_id, node.id])
                else:
                    keypair['machines'] = [[backend_id, node.id],]
                save_keypairs(request, keypair)
        except:
            return Response('Something went wrong with Linode creation', 500)

    else:
        try:
            node = conn.create_node(name=machine_name,
                             image=image,
                             size=size,
                             location=location)
        except Exception as e:
            return Response('Something went wrong with generic node creation: %s' % e, 500)

    return {'id': node.id,
            'name': node.name,
            'extra': node.extra,
            'public_ips': node.public_ips,
            'private_ips': node.private_ips,
            }
예제 #8
0
def create_machine(request):
    """Creates a new virtual machine on the specified backend.

    If the backend is Rackspace it attempts to deploy the node with an ssh key
    provided in config. the method used is the only one working in the old
    Rackspace backend. create_node(), from libcloud.compute.base, with 'auth'
    kwarg doesn't do the trick. Didn't test if you can upload some ssh related
    files using the 'ex_files' kwarg from openstack 1.0 driver.

    In Linode creation is a bit different. There you can pass the key file
    directly during creation. The Linode API also requires to set a disk size
    and doesn't get it from size.id. So, send size.disk from the client and
    use it in all cases just to avoid provider checking. Finally, Linode API
    does not support association between a machine and the image it came from.
    We could set this, at least for machines created through mist.io in
    ex_comment, lroot or lconfig. lroot seems more appropriate. However,
    liblcoud doesn't support linode.config.list at the moment, so no way to
    get them. Also, it will create inconsistencies for machines created
    through mist.io and those from the Linode interface.
    """

    try:
        conn = connect(request)
    except:
        return Response('Backend not found', 404)

    backend_id = request.matchdict['backend']

    try:
        key_name = request.json_body['key']
    except:
        key_name = None

    try:
        keypairs = request.environ['beaker.session']['keypairs']
    except:
        keypairs = request.registry.settings.get('keypairs', {})

    if key_name:
        keypair = get_keypair_by_name(keypairs, key_name)
    else:
        keypair = get_keypair(keypairs)

    if keypair:
        private_key = keypair['private']
        public_key = keypair['public']
    else:
        private_key = public_key = None

    try:
        machine_name = request.json_body['name']
        location_id = request.json_body['location']
        image_id = request.json_body['image']
        size_id = request.json_body['size']
        #deploy_script received as unicode, but ScriptDeployment wants str
        script = str(request.json_body.get('script', ''))
        # these are required only for Linode, passing them anyway
        image_extra = request.json_body['image_extra']
        disk = request.json_body['disk']
    except Exception as e:
        return Response('Invalid payload', 400)

    size = NodeSize(size_id,
                    name='',
                    ram='',
                    disk=disk,
                    bandwidth='',
                    price='',
                    driver=conn)
    image = NodeImage(image_id, name='', extra=image_extra, driver=conn)

    if conn.type in EC2_PROVIDERS:
        locations = conn.list_locations()
        for loc in locations:
            if loc.id == location_id:
                location = loc
                break
    else:
        location = NodeLocation(location_id, name='', country='', driver=conn)

    if conn.type in [Provider.RACKSPACE_FIRST_GEN, Provider.RACKSPACE] and\
    public_key:
        key = SSHKeyDeployment(str(public_key))
        deploy_script = ScriptDeployment(script)
        msd = MultiStepDeployment([key, deploy_script])
        try:
            node = conn.deploy_node(name=machine_name,
                                    image=image,
                                    size=size,
                                    location=location,
                                    deploy=msd)
            if keypair:
                machines = keypair.get('machines', None)
                if machines and len(machines):
                    keypair['machines'].append([backend_id, node.id])
                else:
                    keypair['machines'] = [
                        [backend_id, node.id],
                    ]
                save_keypairs(request, keypair)
        except Exception as e:
            return Response(
                'Something went wrong with node creation in RackSpace: %s' % e,
                500)
    elif conn.type in EC2_PROVIDERS and public_key:
        imported_key = import_key(conn, public_key, key_name)
        created_security_group = create_security_group(conn, EC2_SECURITYGROUP)
        deploy_script = ScriptDeployment(script)

        (tmp_key, tmp_key_path) = tempfile.mkstemp()
        key_fd = os.fdopen(tmp_key, 'w+b')
        key_fd.write(private_key)
        key_fd.close()
        #deploy_node wants path for ssh private key
        if imported_key and created_security_group:
            try:
                node = conn.deploy_node(
                    name=machine_name,
                    image=image,
                    size=size,
                    deploy=deploy_script,
                    location=location,
                    ssh_key=tmp_key_path,
                    ex_keyname=key_name,
                    ex_securitygroup=EC2_SECURITYGROUP['name'])

                if keypair:
                    machines = keypair.get('machines', None)
                    if machines and len(machines):
                        keypair['machines'].append([backend_id, node.id])
                    else:
                        keypair['machines'] = [
                            [backend_id, node.id],
                        ]
                    save_keypairs(request, keypair)
            except Exception as e:
                return Response(
                    'Something went wrong with node creation in EC2: %s' % e,
                    500)
        #remove temp file with private key
        try:
            os.remove(tmp_key_path)
        except:
            pass
    elif conn.type is Provider.LINODE and public_key:
        auth = NodeAuthSSHKey(public_key)
        deploy_script = ScriptDeployment(script)
        try:
            node = conn.create_node(name=machine_name,
                                    image=image,
                                    size=size,
                                    deploy=deploy_script,
                                    location=location,
                                    auth=auth)
            if keypair:
                machines = keypair.get('machines', None)
                if machines and len(machines):
                    keypair['machines'].append([backend_id, node.id])
                else:
                    keypair['machines'] = [
                        [backend_id, node.id],
                    ]
                save_keypairs(request, keypair)
        except:
            return Response('Something went wrong with Linode creation', 500)

    else:
        try:
            node = conn.create_node(name=machine_name,
                                    image=image,
                                    size=size,
                                    location=location)
        except Exception as e:
            return Response(
                'Something went wrong with generic node creation: %s' % e, 500)

    return {
        'id': node.id,
        'name': node.name,
        'extra': node.extra,
        'public_ips': node.public_ips,
        'private_ips': node.private_ips,
    }