Esempio n. 1
0
    def launch(self, inf, radl, requested_radl, num_vm, auth_data):
        server = ServerProxy(self.server_url, allow_none=True)
        session_id = self.getSessionID(auth_data)
        if session_id is None:
            return [(
                False,
                "Incorrect auth data, username and password must be specified for OpenNebula provider."
            )]

        sgs = self.create_security_groups(inf, radl, auth_data)

        system = radl.systems[0]
        # Currently ONE plugin prioritizes user-password credentials
        if system.getValue('disk.0.os.credentials.password'):
            system.delValue('disk.0.os.credentials.private_key')
            system.delValue('disk.0.os.credentials.public_key')

        res = []
        i = 0
        while i < num_vm:
            vm = VirtualMachine(inf, None, self.cloud, radl, requested_radl,
                                self)
            vm.destroy = True
            inf.add_vm(vm)
            template = self.getONETemplate(vm.info, sgs, auth_data, vm)

            self.log_debug("ONE Template: %s" % template)

            success, res_id = server.one.vm.allocate(session_id, template)[0:2]

            if success:
                vm.id = str(res_id)
                vm.info.systems[0].setValue('instance_id', str(res_id))
                vm.destroy = False
                res.append((success, vm))
            else:
                res.append((success, "ERROR: " + str(res_id)))
            i += 1

        return res
Esempio n. 2
0
    def launch(self, inf, radl, requested_radl, num_vm, auth_data):
        service_name = None
        region = self.DEFAULT_LOCATION
        if radl.systems[0].getValue('availability_zone'):
            region = radl.systems[0].getValue('availability_zone')
        else:
            radl.systems[0].setValue('availability_zone', region)

        res = []
        i = 0
        while i < num_vm:
            try:
                subscription_id = self.get_subscription_id(auth_data)

                # Create storage account
                storage_account_name = self.get_storage_name(
                    subscription_id, region)
                storage_account = self.get_storage_account(
                    storage_account_name, auth_data)
                if not storage_account:
                    storage_account_name, error_msg = self.create_storage_account(
                        storage_account_name, auth_data, region)
                    if not storage_account_name:
                        res.append((False, error_msg))
                        break
                else:
                    # if the user has specified the region
                    if radl.systems[0].getValue('availability_zone'):
                        # Check that the region of the storage account is the
                        # same of the service
                        if region != storage_account.GeoPrimaryRegion:
                            res.append(
                                (False,
                                 ("Error creating the service. The specified "
                                  "region is not the same of the service.")))
                            break
                    else:
                        # Otherwise use the storage account region
                        region = storage_account.GeoPrimaryRegion

                # and the service
                service_name, error_msg = self.create_service(
                    auth_data, region)
                if service_name is None:
                    res.append((False, error_msg))
                    break

                self.log_info("Creating the VM with id: " + service_name)

                # Create the VM to get the nodename
                vm = VirtualMachine(inf, service_name, self.cloud, radl,
                                    requested_radl, self)
                vm.destroy = True
                inf.add_vm(vm)
                vm.info.systems[0].setValue('instance_id', str(vm.id))

                # Generate the XML to create the VM
                vm_create_xml = self.get_azure_vm_create_xml(
                    vm, storage_account_name, radl, i, auth_data)

                if vm_create_xml is None:
                    self.delete_service(service_name, auth_data)
                    res.append((False, "Incorrect image or auth data"))
                    break

                uri = "/services/hostedservices/%s/deployments" % service_name
                headers = {
                    'x-ms-version': '2013-03-01',
                    'Content-Type': 'application/xml'
                }
                resp = self.create_request('POST', uri, auth_data, headers,
                                           vm_create_xml)

                if resp.status_code != 202:
                    self.delete_service(service_name, auth_data)
                    self.log_error("Error creating the VM: Error Code " +
                                   str(resp.status_code) + ". Msg: " +
                                   resp.text)
                    res.append((False, "Error creating the VM: Error Code " +
                                str(resp.status_code) + ". Msg: " + resp.text))
                else:
                    vm.destroy = False
                    # Call the GET OPERATION STATUS until sea 200 (OK)
                    request_id = resp.headers['x-ms-request-id']
                    success = self.wait_operation_status(request_id, auth_data)
                    if success:
                        res.append((True, vm))
                    else:
                        self.log_exception("Error waiting the VM creation")
                        self.delete_service(service_name, auth_data)
                        res.append((False, "Error waiting the VM creation"))

            except Exception as ex:
                self.log_exception("Error creating the VM")
                if service_name:
                    self.delete_service(service_name, auth_data)
                res.append((False, "Error creating the VM: " + str(ex)))

            i += 1
        return res
Esempio n. 3
0
    def launch(self, inf, radl, requested_radl, num_vm, auth_data):
        driver = self.get_driver(auth_data)

        system = radl.systems[0]
        image_id = self.get_image_id(system.getValue("disk.0.image.url"))
        image = NodeImage(id=image_id, name=None, driver=driver)

        instance_type = self.get_instance_type(driver.list_sizes(), system)

        name = system.getValue("instance_name")
        if not name:
            name = system.getValue("disk.0.image.name")
        if not name:
            name = "userimage"

        sgs = self.create_security_groups(driver, inf, radl)

        args = {
            'size': instance_type,
            'image': image,
            'ex_security_groups': sgs,
            'name': "%s-%s" % (name, str(uuid.uuid1()))
        }

        if system.getValue('availability_zone'):
            args['location'] = system.getValue('availability_zone')

        keypair = None
        public_key = system.getValue("disk.0.os.credentials.public_key")

        if public_key and public_key.find('-----BEGIN CERTIFICATE-----') == -1:
            public_key = None
            keypair = driver.get_key_pair(public_key)
            if keypair:
                system.setUserKeyCredentials(system.getCredentials().username,
                                             None, keypair.private_key)
            else:
                args["ex_keyname"] = keypair.name
        else:
            public_key, private_key = self.keygen()
            system.setUserKeyCredentials(system.getCredentials().username,
                                         None, private_key)

        user = system.getValue('disk.0.os.credentials.username')
        if not user:
            user = self.DEFAULT_USER
            system.setValue('disk.0.os.credentials.username', user)

        tags = self.get_instance_tags(system)

        res = []
        i = 0
        while i < num_vm:
            self.log_debug("Creating node")

            vm = VirtualMachine(inf, None, self.cloud, radl, requested_radl,
                                self.cloud.getCloudConnector(inf))
            vm.destroy = True
            inf.add_vm(vm)
            cloud_init = self.get_cloud_init_data(radl, vm, public_key, user)

            if cloud_init:
                args['ex_userdata'] = cloud_init

            msg = "Error creating the node"
            try:
                node = driver.create_node(**args)
            except Exception as ex:
                msg += ": %s" % str(ex)
                self.log_exception("Error creating node.")
                node = None

            if node:
                if tags:
                    try:
                        driver.ex_create_tags([node.id], tags)
                    except:
                        self.log_exception("Error adding tags to node %s." %
                                           node.id)

                vm.id = node.id
                vm.info.systems[0].setValue('instance_id', str(node.id))
                vm.info.systems[0].setValue('instance_name', str(node.name))
                if 'zone_name' in node.extra:
                    vm.info.systems[0].setValue('availability_zone',
                                                node.extra["zone_name"])
                self.log_debug("Node successfully created.")
                vm.destroy = False
                inf.add_vm(vm)
                res.append((True, vm))
            else:
                res.append((False, msg))

            i += 1

        return res
Esempio n. 4
0
    def launch(self, inf, radl, requested_radl, num_vm, auth_data):
        system = radl.systems[0]

        public_net = None
        for net in radl.networks:
            if net.isPublic():
                public_net = net

        outports = None
        if public_net:
            outports = public_net.getOutPorts()

        apiVersion = self.get_api_version(auth_data)

        res = []
        # First create the namespace for the infrastructure
        namespace = inf.id
        headers = {'Content-Type': 'application/json'}
        uri = "/api/" + apiVersion + "/namespaces"
        with inf._lock:
            resp = self.create_request('GET', uri + "/" + namespace, auth_data,
                                       headers)
            if resp.status_code != 200:
                namespace_data = {
                    'apiVersion': apiVersion,
                    'kind': 'Namespace',
                    'metadata': {
                        'name': namespace
                    }
                }
                body = json.dumps(namespace_data)
                resp = self.create_request('POST', uri, auth_data, headers,
                                           body)

                if resp.status_code != 201:
                    for _ in range(num_vm):
                        res.append(
                            (False,
                             "Error creating the Namespace: " + resp.text))
                        return res

        i = 0
        while i < num_vm:
            try:
                i += 1

                vm = VirtualMachine(inf, None, self.cloud, radl,
                                    requested_radl, self)
                vm.destroy = True
                inf.add_vm(vm)
                (nodename, _) = vm.getRequestedName(
                    default_hostname=Config.DEFAULT_VM_NAME,
                    default_domain=Config.DEFAULT_DOMAIN)
                pod_name = nodename

                # Do not use the Persistent volumes yet
                volumes = self._create_volumes(apiVersion, namespace, system,
                                               pod_name, auth_data)

                ssh_port = (KubernetesCloudConnector._port_base_num +
                            KubernetesCloudConnector._port_counter) % 65535
                KubernetesCloudConnector._port_counter += 1
                pod_data = self._generate_pod_data(apiVersion, namespace,
                                                   pod_name, outports, system,
                                                   ssh_port, volumes)
                body = json.dumps(pod_data)

                uri = "/api/" + apiVersion + "/namespaces/" + namespace + "/pods"
                resp = self.create_request('POST', uri, auth_data, headers,
                                           body)

                if resp.status_code != 201:
                    res.append(
                        (False, "Error creating the Container: " + resp.text))
                    try:
                        self._delete_volume_claims(pod_data, auth_data)
                    except:
                        self.log_exception("Error deleting volumes.")
                else:
                    output = json.loads(resp.text)
                    vm.id = output["metadata"]["name"]
                    # Set SSH port in the RADL info of the VM
                    vm.setSSHPort(ssh_port)
                    # Set the default user and password to access the container
                    vm.info.systems[0].setValue(
                        'disk.0.os.credentials.username', 'root')
                    vm.info.systems[0].setValue(
                        'disk.0.os.credentials.password', self._root_password)
                    vm.info.systems[0].setValue('instance_id', str(vm.id))
                    vm.info.systems[0].setValue('instance_name', str(vm.id))

                    vm.destroy = False
                    res.append((True, vm))

            except Exception as ex:
                self.log_exception(
                    "Error connecting with Kubernetes API server")
                res.append((False, "ERROR: " + str(ex)))

        return res
Esempio n. 5
0
    def test_commands(self, bottle_request, check_auth_data,
                      get_infrastructure, SSH):
        """Test REST StopInfrastructure."""
        bottle_request.return_value = MagicMock()
        bottle_request.headers = {
            "AUTHORIZATION":
            ("type = InfrastructureManager; username = user; password = pass\n"
             "id = one; type = OpenNebula; host = onedock.i3m.upv.es:2633; "
             "username = user; password = pass")
        }
        bottle_request.environ = {'HTTP_HOST': 'imserver.com'}

        inf = InfrastructureInfo()
        inf.id = "1"
        inf.auth = Authentication([{
            'type': 'InfrastructureManager',
            'username': '******',
            'password': '******'
        }])
        get_infrastructure.return_value = inf

        bottle_request.params = {'step': '1'}
        res = RESTGetVMProperty("1", "1", "command")
        auth_str = "Authorization: type = InfrastructureManager; username = user; password = pass"
        url = "http://imserver.com/infrastructures/1/vms/1/command?step=2"
        expected_res = """
                res="wait"
                while [ "$res" == "wait" ]
                do
                  res=`curl -s -H "%s" -H "Accept: text/plain" %s`
                  if [ "$res" != "wait" ]
                  then
                    eval "$res"
                  else
                    sleep 20
                  fi
                done""" % (auth_str, url)
        self.assertEqual(res, expected_res)

        radl_master = parse_radl("""
            network publica (outbound = 'yes')
            network privada ()

            system front (
            cpu.arch='x86_64' and
            cpu.count>=1 and
            memory.size>=512m and
            net_interface.0.ip = '8.8.8.8' and
            net_interface.0.connection = 'publica' and
            net_interface.1.connection = 'privada' and
            disk.0.image.url = 'mock0://linux.for.ev.er' and
            disk.0.os.credentials.username = '******' and
            disk.0.os.credentials.password = '******' and
            disk.0.os.name = 'linux'
            )
        """)

        radl_vm1 = parse_radl("""
            network privada ()

            system wn (
            cpu.arch='x86_64' and
            cpu.count>=1 and
            memory.size>=512m and
            net_interface.0.connection = 'privada' and
            disk.0.image.url = 'mock0://linux.for.ev.er' and
            disk.0.os.credentials.username = '******' and
            disk.0.os.credentials.password = '******' and
            disk.0.os.name = 'linux'
            )
        """)

        radl_vm2 = parse_radl("""
            network privada2 ()

            system wn2 (
            cpu.arch='x86_64' and
            cpu.count>=1 and
            memory.size>=512m and
            net_interface.0.connection = 'privada2' and
            disk.0.image.url = 'mock0://linux.for.ev.er' and
            disk.0.os.credentials.username = '******' and
            disk.0.os.credentials.password = '******' and
            disk.0.os.name = 'linux'
            )
        """)

        # in the Master VM
        bottle_request.params = {'step': '2'}
        inf.vm_master = VirtualMachine(inf, None, None, radl_master,
                                       radl_master)
        inf.vm_master.creation_im_id = 0
        ssh = MagicMock()
        ssh.test_connectivity.return_value = True
        ssh.port = 22
        ssh.private_key = None
        ssh.password = "******"
        ssh.username = "******"
        ssh.host = "8.8.8.8"
        SSH.return_value = ssh
        vm1 = VirtualMachine(inf, None, None, radl_vm1, radl_vm1)
        vm1.creation_im_id = 1
        vm1.destroy = False
        vm2 = VirtualMachine(inf, None, None, radl_vm2, radl_vm2)
        vm2.creation_im_id = 2
        vm2.destroy = False
        inf.vm_list = [inf.vm_master, vm1, vm2]

        res = RESTGetVMProperty("1", "0", "command")
        expected_res = "true"
        self.assertEqual(res, expected_res)

        bottle_request.params = {'step': '2'}
        res = RESTGetVMProperty("1", "1", "command")
        expected_res = "true"
        self.assertEqual(res, expected_res)

        # in VM not connected to the Master VM
        res = RESTGetVMProperty("1", "2", "command")
        expected_res = (
            'sshpass -pyoyoyo ssh -N -R 20002:localhost:22 -p 22 -o "UserKnownHostsFile=/dev/null"'
            ' -o "StrictHostKeyChecking=no" [email protected] &')
        self.assertEqual(res, expected_res)
Esempio n. 6
0
    def launch(self, inf, radl, requested_radl, num_vm, auth_data):
        system = radl.systems[0]

        # Get the public network connected with this VM
        public_net = None
        for net in radl.networks:
            if net.isPublic() and system.getNumNetworkWithConnection(net.id) is not None:
                public_net = net

        outports = None
        if public_net:
            outports = public_net.getOutPorts()

        self._create_networks(inf, radl, auth_data)

        with inf._lock:
            self._create_volumes(system, auth_data)

        headers = {'Content-Type': 'application/json'}
        res = []
        i = 0
        while i < num_vm:
            try:
                i += 1
                # Create the VM to get the nodename
                vm = VirtualMachine(inf, None, self.cloud, radl, requested_radl, self)
                vm.destroy = True
                inf.add_vm(vm)

                ssh_port = 22
                if vm.hasPublicNet():
                    ssh_port = (DockerCloudConnector._port_base_num +
                                DockerCloudConnector._port_counter) % 65535
                    DockerCloudConnector._port_counter += 1

                # The URI has this format: docker://image_name
                full_image_name = system.getValue("disk.0.image.url")[9:]

                # Create the container
                if self._is_swarm(auth_data):
                    cont_data = self._generate_create_svc_request_data(full_image_name, outports, vm,
                                                                       ssh_port, auth_data)
                    resp = self.create_request('POST', "/services/create", auth_data, headers, cont_data)
                else:
                    # First we have to pull the image
                    image_parts = full_image_name.split(":")
                    image_name = image_parts[0]
                    if len(image_parts) < 2:
                        tag = "latest"
                    else:
                        tag = image_parts[1]
                    resp = self.create_request('POST', "/images/create?fromImage=%s&tag=%s" % (image_name, tag),
                                               auth_data, headers)

                    if resp.status_code not in [201, 200]:
                        res.append((False, "Error pulling the image: " + resp.text))
                        continue

                    cont_data = self._generate_create_cont_request_data(full_image_name, outports, vm, ssh_port)
                    resp = self.create_request('POST', "/containers/create", auth_data, headers, cont_data)

                if resp.status_code != 201:
                    res.append((False, "Error creating the Container: " + resp.text))
                    continue

                output = json.loads(resp.text)
                # Set the cloud id to the VM
                if "Id" in output:
                    vm.id = output["Id"]
                elif "ID" in output:
                    vm.id = output["ID"]
                else:
                    res.append((False, "Error: response format not expected."))

                vm.info.systems[0].setValue('instance_id', str(vm.id))

                if not self._is_swarm(auth_data):
                    # In creation a container can only be attached to one one network
                    # so now we must attach to the rest of networks (if any)
                    success = self._attach_cont_to_networks(vm, auth_data)
                    if not success:
                        res.append((False, "Error attaching to networks the Container"))
                        # Delete the container
                        resp = self.create_request('DELETE', "/containers/" + vm.id, auth_data)
                        continue

                    # Now start it
                    success, msg = self.start(vm, auth_data)
                    if not success:
                        res.append((False, "Error starting the Container: " + str(msg)))
                        # Delete the container
                        resp = self.create_request('DELETE', "/containers/" + vm.id, auth_data)
                        continue

                # Set the default user and password to access the container
                vm.info.systems[0].setValue('disk.0.os.credentials.username', 'root')
                vm.info.systems[0].setValue('disk.0.os.credentials.password', self._root_password)

                # Set ssh port in the RADL info of the VM
                vm.setSSHPort(ssh_port)

                vm.destroy = False
                res.append((True, vm))

            except Exception as ex:
                self.log_exception("Error connecting with Docker server")
                res.append((False, "ERROR: " + str(ex)))

        return res