Exemple #1
0
    def _to_node(self, vm, driver):
        """
        Generates the :class:`Node` class.
        """
        identifier = vm.findtext('id')
        name = vm.findtext('nodeName')
        state = AbiquoResponse.NODE_STATE_MAP[vm.findtext('state')]

        link_image = get_href(vm, 'virtualmachinetemplate')
        image_element = self.connection.request(link_image).object
        repo_link = get_href(image_element, 'datacenterrepository')
        image = self._to_nodeimage(image_element, self, repo_link)

        ## Fill the 'ips' data
        private_ips = []
        public_ips = []
        nics_element = self.connection.request(get_href(vm, 'nics')).object
        for nic in nics_element.findall('nic'):
            ip = nic.findtext('ip')
            for link in nic.findall('link'):
                rel = link.attrib['rel']
                if rel == 'privatenetwork':
                    private_ips.append(ip)
                elif rel in ['publicnetwork', 'externalnetwork',
                             'unmanagednetwork']:
                    public_ips.append(ip)

        extra = {'uri_id': get_href(vm, 'edit')}

        if vm.find('vdrpIp') is not None:
            extra['vdrp_ip'] = vm.findtext('vdrpIP')
            extra['vdrp_port'] = vm.findtext('vdrpPort')

        return Node(identifier, name, state, public_ips, private_ips,
                    driver, image=image, extra=extra)
Exemple #2
0
    def ex_list_groups(self, location=None):
        """
        List all groups.

        :param location: filter the groups by location (optional)
        :type  location: a :class:`NodeLocation` instance.

        :return:         the list of :class:`NodeGroup`
        """
        groups = []
        for vdc in self._get_locations(location):
            link_vdc = self.connection.context['locations'][vdc]
            e_vdc = self.connection.request(link_vdc).object
            apps_link = get_href(e_vdc, 'virtualappliances')
            vapps = self.connection.request(apps_link).object
            for vapp in vapps.findall('virtualAppliance'):
                nodes = []
                vms_link = get_href(vapp, 'virtualmachines')
                headers = {'Accept': self.NODES_MIME_TYPE}
                vms = self.connection.request(vms_link, headers=headers).object
                for vm in vms.findall('virtualmachinewithnode'):
                    nodes.append(self._to_node(vm, self))

                group = NodeGroup(self, vapp.findtext('name'),
                                  nodes, get_href(vapp, 'edit'))
                groups.append(group)

        return groups
Exemple #3
0
    def _to_node(self, vm, driver):
        """
        Generates the L{Node} class.
        """
        identifier = vm.findtext('id')
        name = vm.findtext('nodeName')
        state = AbiquoResponse.NODE_STATE_MAP[vm.findtext('state')]

        link_image = get_href(vm, 'virtualmachinetemplate')
        image_element = self.connection.request(link_image).object
        repo_link = get_href(image_element, 'datacenterrepository')
        image = self._to_nodeimage(image_element, self, repo_link)

        ## Fill the 'ips' data
        private_ips = []
        public_ips = []
        nics_element = self.connection.request(get_href(vm, 'nics')).object
        for nic in nics_element.findall('nic'):
            ip = nic.findtext('ip')
            for link in nic.findall('link'):
                rel = link.attrib['rel']
                if rel == 'privatenetwork':
                    private_ips.append(ip)
                elif rel in ['publicnetwork', 'externalnetwork',
                             'unmanagednetwork']:
                    public_ips.append(ip)

        extra = {'uri_id': get_href(vm, 'edit')}

        if vm.find('vdrpIp') is not None:
            extra['vdrp_ip'] = vm.findtext('vdrpIP')
            extra['vdrp_port'] = vm.findtext('vdrpPort')

        return Node(identifier, name, state, public_ips, private_ips,
                    driver, image=image, extra=extra)
Exemple #4
0
    def ex_list_groups(self, location=None):
        """
        List all groups.

        :param location: filter the groups by location (optional)
        :type  location: a :class:`NodeLocation` instance.

        :return:         the list of :class:`NodeGroup`
        """
        groups = []
        for vdc in self._get_locations(location):
            link_vdc = self.connection.cache['locations'][vdc]
            hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
            e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object
            apps_link = get_href(e_vdc, 'virtualappliances')
            hdr_vapps = {'Accept': self.VAPPS_MIME_TYPE}
            vapps = self.connection.request(apps_link,
                                            headers=hdr_vapps).object
            for vapp in vapps.findall('virtualAppliance'):
                nodes = []
                vms_link = get_href(vapp, 'virtualmachines')
                headers = {'Accept': self.NODES_MIME_TYPE}
                vms = self.connection.request(vms_link, headers=headers).object
                for vm in vms.findall('virtualMachine'):
                    nodes.append(self._to_node(vm, self))
                group = NodeGroup(self, vapp.findtext('name'),
                                  nodes, get_href(vapp, 'edit'))
                groups.append(group)

        return groups
Exemple #5
0
    def _define_create_node_group(self, xml_loc, loc, group_name=None):
        """
        Search for a group where to create the node.

        If we can not find any group, create it into argument 'location'
        """
        if not group_name:
            group_name = NodeGroup.DEFAULT_GROUP_NAME

        # We search if the group is already defined into the location
        groups_link = get_href(xml_loc, "virtualappliances")
        groups_hdr = {"Accept": self.VAPPS_MIME_TYPE}
        vapps_element = self.connection.request(groups_link,
                                                headers=groups_hdr).object
        target_group = None
        for vapp in vapps_element.findall("virtualAppliance"):
            if vapp.findtext("name") == group_name:
                uri_vapp = get_href(vapp, "edit")
                return NodeGroup(self, vapp.findtext("name"), uri=uri_vapp)

        # target group not found: create it. Since it is an extension of
        # the basic 'libcloud' functionality, we try to be as flexible as
        # possible.
        if target_group is None:
            return self.ex_create_group(group_name, loc)
Exemple #6
0
    def _define_create_node_group(self, xml_loc, loc, **kwargs):
        """
        Search for a group where to create the node.

        If we can not find any group, create it into argument 'location'
        """
        if 'group_name' not in kwargs:
            group_name = NodeGroup.DEFAULT_GROUP_NAME
        else:
            group_name = kwargs['group_name']

        # We search if the group is already defined into the location
        groups_link = get_href(xml_loc, 'virtualappliances')
        groups_hdr = {'Accept': self.VAPPS_MIME_TYPE}
        vapps_element = self.connection.request(groups_link,
                                                headers=groups_hdr).object
        target_group = None
        for vapp in vapps_element.findall('virtualAppliance'):
            if vapp.findtext('name') == group_name:
                uri_vapp = get_href(vapp, 'edit')
                return NodeGroup(self, vapp.findtext('name'), uri=uri_vapp)

        # target group not found: create it. Since it is an extension of
        # the basic 'libcloud' functionality, we try to be as flexible as
        # possible.
        if target_group is None:
            return self.ex_create_group(group_name, loc)
Exemple #7
0
    def ex_list_groups(self, location=None):
        """
        List all groups.

        @param location: filter the groups by location (optional)
        @type  location: a L{NodeLocation} instance.

        @return:         the list of L{NodeGroup}
        """
        groups = []
        for vdc in self._get_locations(location):
            link_vdc = self.connection.context['locations'][vdc]
            e_vdc = self.connection.request(link_vdc).object
            apps_link = get_href(e_vdc, 'virtualappliances')
            vapps = self.connection.request(apps_link).object
            for vapp in vapps.findall('virtualAppliance'):
                nodes = []
                vms_link = get_href(vapp, 'virtualmachines')
                headers = {'Accept': self.NODES_MIME_TYPE}
                vms = self.connection.request(vms_link, headers=headers).object
                for vm in vms.findall('virtualmachinewithnode'):
                    nodes.append(self._to_node(vm, self))

                group = NodeGroup(self, vapp.findtext('name'),
                                  nodes, get_href(vapp, 'edit'))
                groups.append(group)

        return groups
Exemple #8
0
    def _define_create_node_group(self, xml_loc, loc, **kwargs):
        """
        Search for a group where to create the node.

        If we can not find any group, create it into argument 'location'
        """
        if not 'group_name' in kwargs:
            group_name = NodeGroup.DEFAULT_GROUP_NAME
        else:
            group_name = kwargs['group_name']

        # We search if the group is already defined into the location
        groups_link = get_href(xml_loc, 'virtualappliances')
        vapps_element = self.connection.request(groups_link).object
        target_group = None
        for vapp in vapps_element.findall('virtualAppliance'):
            if vapp.findtext('name') == group_name:
                uri_vapp = get_href(vapp, 'edit')
                return NodeGroup(self, vapp.findtext('name'), uri=uri_vapp)

        # target group not found: create it. Since it is an extension of
        # the basic 'libcloud' functionality, we try to be as flexible as
        # possible.
        if target_group is None:
            return self.ex_create_group(group_name, loc)
Exemple #9
0
    def ex_list_groups(self, location=None):
        """
        List all groups.

        :param location: filter the groups by location (optional)
        :type  location: a :class:`NodeLocation` instance.

        :return:         the list of :class:`NodeGroup`
        """
        groups = []
        for vdc in self._get_locations(location):
            link_vdc = self.connection.cache["locations"][vdc]
            hdr_vdc = {"Accept": self.VDC_MIME_TYPE}
            e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object
            apps_link = get_href(e_vdc, "virtualappliances")
            hdr_vapps = {"Accept": self.VAPPS_MIME_TYPE}
            vapps = self.connection.request(apps_link,
                                            headers=hdr_vapps).object
            for vapp in vapps.findall("virtualAppliance"):
                nodes = []
                vms_link = get_href(vapp, "virtualmachines")
                headers = {"Accept": self.NODES_MIME_TYPE}
                vms = self.connection.request(vms_link, headers=headers).object
                for vm in vms.findall("virtualMachine"):
                    nodes.append(self._to_node(vm, self))
                group = NodeGroup(self, vapp.findtext("name"), nodes,
                                  get_href(vapp, "edit"))
                groups.append(group)

        return groups
Exemple #10
0
    def ex_populate_cache(self):
        """
        Populate the cache.

        For each connection, it is good to store some objects that will be
        useful for further requests, such as the 'user' and the 'enterprise'
        objects.

        Executes the 'login' resource after setting the connection parameters
        and, if the execution is successful, it sets the 'user' object into
        cache. After that, it also requests for the 'enterprise' and
        'locations' data.

        List of locations should remain the same for a single libcloud
        connection. However, this method is public and you are able to
        refresh the list of locations any time.
        """

        user_headers = {'Accept': self.USER_MIME_TYPE}
        user = self.connection.request('/login', headers=user_headers).object
        self.connection.cache['user'] = user
        e_ent = get_href(self.connection.cache['user'],
                         'enterprise')
        ent_headers = {'Accept': self.ENT_MIME_TYPE}
        ent = self.connection.request(e_ent, headers=ent_headers).object
        self.connection.cache['enterprise'] = ent

        vdcs_headers = {'Accept': self.VDCS_MIME_TYPE}
        uri_vdcs = '/cloud/virtualdatacenters'
        e_vdcs = self.connection.request(uri_vdcs, headers=vdcs_headers).object

        params = {"idEnterprise": self._get_enterprise_id()}

        dcs_headers = {'Accept': self.DCS_MIME_TYPE}
        e_dcs = self.connection.request('/admin/datacenters',
                                        headers=dcs_headers,
                                        params=params).object
        dc_dict = {}
        for dc in e_dcs.findall('datacenter'):
            key = get_href(dc, 'self')
            dc_dict[key] = dc

        # Populate locations name cache
        self.connection.cache['locations'] = {}
        for e_vdc in e_vdcs.findall('virtualDatacenter'):
            loc = get_href(e_vdc, 'location')
            if loc is not None:
                self.connection.cache['locations'][loc] = get_href(e_vdc,
                                                                   'edit')
Exemple #11
0
    def _to_node(self, vm, driver):
        """
        Generates the :class:`Node` class.
        """
        identifier = vm.findtext("id")
        name = vm.findtext("label")
        state = AbiquoResponse.NODE_STATE_MAP[vm.findtext("state")]

        link_image = get_href(vm, "virtualmachinetemplate")
        link_hdr = {"Accept": self.VMTPL_MIME_TYPE}
        image_element = self.connection.request(link_image,
                                                headers=link_hdr).object
        repo_link = get_href(image_element, "datacenterrepository")
        image = self._to_nodeimage(image_element, self, repo_link)

        # Fill the 'ips' data
        private_ips = []
        public_ips = []
        nics_hdr = {"Accept": self.NICS_MIME_TYPE}
        nics_element = self.connection.request(get_href(vm, "nics"),
                                               headers=nics_hdr).object
        for nic in nics_element.findall("nic"):
            ip = nic.findtext("ip")
            for link in nic.findall("link"):
                rel = link.attrib["rel"]
                if rel == "privatenetwork":
                    private_ips.append(ip)
                elif rel in [
                        "publicnetwork", "externalnetwork", "unmanagednetwork"
                ]:
                    public_ips.append(ip)

        extra = {"uri_id": get_href(vm, "edit")}

        if vm.find("vdrpIp") is not None:
            extra["vdrp_ip"] = vm.findtext("vdrpIP")
            extra["vdrp_port"] = vm.findtext("vdrpPort")

        return Node(
            identifier,
            name,
            state,
            public_ips,
            private_ips,
            driver,
            image=image,
            extra=extra,
        )
Exemple #12
0
    def ex_set_context(self):
        """
        Generates the context

        For each connection, it is good to store some objects that will be
        useful for further requests, such as the 'user' and the 'enterprise'
        objects.

        Executes the 'login' resource after setting the connection parameters
        and, if the execution is successful, it sets the 'user' object into
        context. After that, it also requests for the 'enterprise' and
        'locations' data.

        List of locations should remain the same for a single libcloud
        connection. However, this method is public and you are able to
        refresh the list of locations any time.
        """
        user = self.connection.request('/login').object
        self.connection.context['user'] = user
        e_ent = get_href(self.connection.context['user'],
                         'enterprise')
        ent = self.connection.request(e_ent).object
        self.connection.context['enterprise'] = ent

        uri_vdcs = '/cloud/virtualdatacenters'
        e_vdcs = self.connection.request(uri_vdcs).object

        # Set a dict for the datacenter and its href for a further search
        params = {"idEnterprise": self._get_enterprise_id()}
        e_dcs = self.connection.request('/admin/datacenters',
                                        params=params).object
        dc_dict = {}
        for dc in e_dcs.findall('datacenter'):
            key = get_href(dc, 'edit')
            dc_dict[key] = dc

        # Set the context for the locations
        self.connection.context['locations'] = {}
        for e_vdc in e_vdcs.findall('virtualDatacenter'):
            dc_link = get_href(e_vdc, 'datacenter')
            loc = self._to_location(e_vdc, dc_dict[dc_link], self)

            # Save into context the link to the itself because we will need
            # it in the future, but we save here to don't extend the class
            # :class:`NodeLocation`.
            # So here we have the dict: :class:`NodeLocation` ->
            # link_datacenter
            self.connection.context['locations'][loc] = get_href(e_vdc, 'edit')
Exemple #13
0
    def ex_populate_cache(self):
        """
        Populate the cache.

        For each connection, it is good to store some objects that will be
        useful for further requests, such as the 'user' and the 'enterprise'
        objects.

        Executes the 'login' resource after setting the connection parameters
        and, if the execution is successful, it sets the 'user' object into
        cache. After that, it also requests for the 'enterprise' and
        'locations' data.

        List of locations should remain the same for a single libcloud
        connection. However, this method is public and you are able to
        refresh the list of locations any time.
        """
        user = self.connection.request('/login').object
        self.connection.cache['user'] = user
        e_ent = get_href(self.connection.cache['user'],
                         'enterprise')
        ent = self.connection.request(e_ent).object
        self.connection.cache['enterprise'] = ent

        uri_vdcs = '/cloud/virtualdatacenters'
        e_vdcs = self.connection.request(uri_vdcs).object

        # Set a dict for the datacenter and its href for a further search
        params = {"idEnterprise": self._get_enterprise_id()}
        e_dcs = self.connection.request('/admin/datacenters',
                                        params=params).object
        dc_dict = {}
        for dc in e_dcs.findall('datacenter'):
            key = get_href(dc, 'edit')
            dc_dict[key] = dc

        # Populate locations cache
        self.connection.cache['locations'] = {}
        for e_vdc in e_vdcs.findall('virtualDatacenter'):
            dc_link = get_href(e_vdc, 'datacenter')
            loc = self._to_location(e_vdc, dc_dict[dc_link], self)

            # Save into cache the link to the itself because we will need
            # it in the future, but we save here to don't extend the class
            # :class:`NodeLocation`.
            # So here we have the dict: :class:`NodeLocation` ->
            # link_datacenter
            self.connection.cache['locations'][loc] = get_href(e_vdc, 'edit')
Exemple #14
0
    def _define_create_node_node(self, group, **kwargs):
        """
        Defines the node before to create.

        In Abiquo, you first need to 'register' or 'define' the node in
        the API before to create it into the target hypervisor.
        """
        vm = ET.Element('virtualmachinewithnode')
        if 'name' in kwargs:
            vmname = ET.SubElement(vm, 'nodeName')
            vmname.text = kwargs['name']
        attrib = {'type': 'application/vnd.abiquo/virtualmachinetemplate+xml',
                  'rel': 'virtualmachinetemplate',
                  'href': kwargs['image'].extra['url']}
        ET.SubElement(vm, 'link', attrib=attrib)
        headers = {'Content-type': self.NODE_MIME_TYPE}

        if 'size' in kwargs:
            # Override the 'NodeSize' data
            ram = ET.SubElement(vm, 'ram')
            ram.text = str(kwargs['size'].ram)
            hd = ET.SubElement(vm, 'hdInBytes')
            hd.text = str(int(kwargs['size'].disk) * self.GIGABYTE)

        # Create the virtual machine
        nodes_link = group.uri + '/virtualmachines'
        vm = self.connection.request(nodes_link, data=tostring(vm),
                                     headers=headers, method='POST').object
        edit_vm = get_href(vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}

        return self.connection.request(edit_vm, headers=headers).object
Exemple #15
0
    def _define_create_node_node(self, group, **kwargs):
        """
        Defines the node before to create.

        In Abiquo, you first need to 'register' or 'define' the node in
        the API before to create it into the target hypervisor.
        """
        vm = ET.Element('virtualMachine')
        if 'name' in kwargs:
            vmname = ET.SubElement(vm, 'label')
            vmname.text = kwargs['name']
        attrib = {'type': self.VMTPL_MIME_TYPE,
                  'rel': 'virtualmachinetemplate',
                  'href': kwargs['image'].extra['url']}
        ET.SubElement(vm, 'link', attrib=attrib)
        headers = {'Accept': self.NODE_MIME_TYPE,
                   'Content-type': self.NODE_MIME_TYPE}

        if 'size' in kwargs:
            # Override the 'NodeSize' data
            ram = ET.SubElement(vm, 'ram')
            ram.text = str(kwargs['size'].ram)
            hd = ET.SubElement(vm, 'hdInBytes')
            hd.text = str(int(kwargs['size'].disk) * self.GIGABYTE)

        # Create the virtual machine
        nodes_link = group.uri + '/virtualmachines'
        vm = self.connection.request(nodes_link, data=tostring(vm),
                                     headers=headers, method='POST').object
        edit_vm = get_href(vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}

        return self.connection.request(edit_vm, headers=headers).object
Exemple #16
0
    def list_images(self, location=None):
        """
        List images on Abiquo Repositories

        :keyword location: The location to list images for.
        :type    location: :class:`NodeLocation`

        :return:           list of node image objects
        :rtype:            ``list`` of :class:`NodeImage`
        """
        enterprise_id = self._get_enterprise_id()
        uri = "/admin/enterprises/%s/datacenterrepositories/" % (enterprise_id)
        repos_hdr = {"Accept": self.DCRS_MIME_TYPE}
        repos = self.connection.request(uri, headers=repos_hdr).object

        images = []
        for repo in repos.findall("datacenterRepository"):
            # filter by location. Skips when the name of the location
            # is different from the 'datacenterRepository' element
            for vdc in self._get_locations(location):
                # Check if the virtual datacenter belongs to this repo
                link_vdc = self.connection.cache["locations"][vdc]
                hdr_vdc = {"Accept": self.VDC_MIME_TYPE}
                e_vdc = self.connection.request(link_vdc,
                                                headers=hdr_vdc).object
                dc_link_vdc = get_href(e_vdc, "location")
                dc_link_repo = get_href(repo, "datacenter")

                if dc_link_vdc.split("/")[-1] == dc_link_repo.split("/")[-1]:
                    # Filter the template in case we don't have it yet
                    url_templates = get_href(repo, "virtualmachinetemplates")
                    hypervisor_type = e_vdc.findtext("hypervisorType")
                    params = {"hypervisorTypeName": hypervisor_type}
                    headers = {"Accept": self.VMTPLS_MIME_TYPE}
                    templates = self.connection.request(url_templates,
                                                        params,
                                                        headers=headers).object
                    for templ in templates.findall("virtualMachineTemplate"):
                        # Avoid duplicated templates
                        id_template = templ.findtext("id")
                        ids = [image.id for image in images]
                        if id_template not in ids:
                            images.append(
                                self._to_nodeimage(templ, self,
                                                   get_href(repo, "edit")))

        return images
Exemple #17
0
    def list_images(self, location=None):
        """
        List images on Abiquo Repositories

        :keyword location: The location to list images for.
        :type    location: :class:`NodeLocation`

        :return:           list of node image objects
        :rtype:            ``list`` of :class:`NodeImage`
        """
        enterprise_id = self._get_enterprise_id()
        uri = '/admin/enterprises/%s/datacenterrepositories/' % (enterprise_id)
        repos_hdr = {'Accept': self.DCRS_MIME_TYPE}
        repos = self.connection.request(uri, headers=repos_hdr).object

        images = []
        for repo in repos.findall('datacenterRepository'):
            # filter by location. Skips when the name of the location
            # is different from the 'datacenterRepository' element
            for vdc in self._get_locations(location):
                # Check if the virtual datacenter belongs to this repo
                link_vdc = self.connection.cache['locations'][vdc]
                hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
                e_vdc = self.connection.request(link_vdc,
                                                headers=hdr_vdc).object
                dc_link_vdc = get_href(e_vdc, 'location')
                dc_link_repo = get_href(repo, 'datacenter')

                if dc_link_vdc.split("/")[-1] == dc_link_repo.split("/")[-1]:
                    # Filter the template in case we don't have it yet
                    url_templates = get_href(repo, 'virtualmachinetemplates')
                    hypervisor_type = e_vdc.findtext('hypervisorType')
                    params = {'hypervisorTypeName': hypervisor_type}
                    headers = {'Accept': self.VMTPLS_MIME_TYPE}
                    templates = self.connection.request(url_templates, params,
                                                        headers=headers).object
                    for templ in templates.findall('virtualMachineTemplate'):
                        # Avoid duplicated templates
                        id_template = templ.findtext('id')
                        ids = [image.id for image in images]
                        if id_template not in ids:
                            images.append(self._to_nodeimage(templ, self,
                                                             get_href(repo,
                                                                      'edit')))

        return images
Exemple #18
0
 def _to_nodeimage(self, template, driver, repo):
     """
     Generates the :class:`NodeImage` class.
     """
     identifier = template.findtext('id')
     name = template.findtext('name')
     url = get_href(template, 'edit')
     extra = {'repo': repo, 'url': url}
     return NodeImage(identifier, name, driver, extra)
Exemple #19
0
 def _to_nodeimage(self, template, driver, repo):
     """
     Generates the L{NodeImage} class.
     """
     identifier = template.findtext('id')
     name = template.findtext('name')
     url = get_href(template, 'edit')
     extra = {'repo': repo, 'url': url}
     return NodeImage(identifier, name, driver, extra)
Exemple #20
0
 def _to_nodeimage(self, template, driver, repo):
     """
     Generates the :class:`NodeImage` class.
     """
     identifier = template.findtext("id")
     name = template.findtext("name")
     url = get_href(template, "edit")
     hdreqd = template.findtext("hdRequired")
     extra = {"repo": repo, "url": url, "hdrequired": hdreqd}
     return NodeImage(identifier, name, driver, extra)
Exemple #21
0
 def _to_nodeimage(self, template, driver, repo):
     """
     Generates the :class:`NodeImage` class.
     """
     identifier = template.findtext('id')
     name = template.findtext('name')
     url = get_href(template, 'edit')
     hdreqd = template.findtext('hdRequired')
     extra = {'repo': repo, 'url': url, 'hdrequired': hdreqd}
     return NodeImage(identifier, name, driver, extra)
Exemple #22
0
    def list_images(self, location=None):
        """
        List images on Abiquo Repositories

        @keyword location: The location to list images for.
        @type    location: L{NodeLocation}

        @return:           list of node image objects
        @rtype:            C{list} of L{NodeImage}
        """
        enterprise_id = self._get_enterprise_id()
        uri = '/admin/enterprises/%s/datacenterrepositories/' % (enterprise_id)
        repos = self.connection.request(uri).object

        images = []
        for repo in repos.findall('datacenterRepository'):
            # filter by location. Skips when the name of the location
            # is different from the 'datacenterRepository' element
            for vdc in self._get_locations(location):
                # Check if the virtual datacenter belongs to this repo
                link_vdc = self.connection.context['locations'][vdc]
                e_vdc = self.connection.request(link_vdc).object
                dc_link_vdc = get_href(e_vdc, 'datacenter')
                dc_link_repo = get_href(repo, 'datacenter')

                if dc_link_vdc == dc_link_repo:
                    # Filter the template in case we don't have it yet
                    url_templates = get_href(repo, 'virtualmachinetemplates')
                    hypervisor_type = e_vdc.findtext('hypervisorType')
                    params = {'hypervisorTypeName': hypervisor_type}
                    templates = self.connection.request(url_templates,
                                                        params).object
                    for templ in templates.findall('virtualMachineTemplate'):
                        # Avoid duplicated templates
                        id_template = templ.findtext('id')
                        ids = [image.id for image in images]
                        if id_template not in ids:
                            images.append(self._to_nodeimage(templ, self,
                                                             get_href(repo,
                                                                      'edit')))

        return images
Exemple #23
0
    def ex_create_group(self, name, location=None):
        """
        Create an empty group.

        You can specify the location as well.

        :param     group:     name of the group (required)
        :type      group:     ``str``

        :param     location: location were to create the group
        :type      location: :class:`NodeLocation`

        :returns:            the created group
        :rtype:              :class:`NodeGroup`
        """
        # prepare the element
        vapp = ET.Element("virtualAppliance")
        vapp_name = ET.SubElement(vapp, "name")
        vapp_name.text = name

        if location is None:
            location = self.list_locations()[0]
        elif location not in self.list_locations():
            raise LibcloudError("Location does not exist")

        link_vdc = self.connection.cache["locations"][location]
        hdr_vdc = {"Accept": self.VDC_MIME_TYPE}
        e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object

        creation_link = get_href(e_vdc, "virtualappliances")
        headers = {
            "Accept": self.VAPP_MIME_TYPE,
            "Content-type": self.VAPP_MIME_TYPE
        }
        vapp = self.connection.request(creation_link,
                                       data=tostring(vapp),
                                       headers=headers,
                                       method="POST").object

        uri_vapp = get_href(vapp, "edit")

        return NodeGroup(self, vapp.findtext("name"), uri=uri_vapp)
Exemple #24
0
    def list_images(self, location=None):
        """
        List images on Abiquo Repositories

        :keyword location: The location to list images for.
        :type    location: :class:`NodeLocation`

        :return:           list of node image objects
        :rtype:            ``list`` of :class:`NodeImage`
        """
        enterprise_id = self._get_enterprise_id()
        uri = '/admin/enterprises/%s/datacenterrepositories/' % (enterprise_id)
        repos = self.connection.request(uri).object

        images = []
        for repo in repos.findall('datacenterRepository'):
            # filter by location. Skips when the name of the location
            # is different from the 'datacenterRepository' element
            for vdc in self._get_locations(location):
                # Check if the virtual datacenter belongs to this repo
                link_vdc = self.connection.context['locations'][vdc]
                e_vdc = self.connection.request(link_vdc).object
                dc_link_vdc = get_href(e_vdc, 'datacenter')
                dc_link_repo = get_href(repo, 'datacenter')

                if dc_link_vdc == dc_link_repo:
                    # Filter the template in case we don't have it yet
                    url_templates = get_href(repo, 'virtualmachinetemplates')
                    hypervisor_type = e_vdc.findtext('hypervisorType')
                    params = {'hypervisorTypeName': hypervisor_type}
                    templates = self.connection.request(url_templates,
                                                        params).object
                    for templ in templates.findall('virtualMachineTemplate'):
                        # Avoid duplicated templates
                        id_template = templ.findtext('id')
                        ids = [image.id for image in images]
                        if id_template not in ids:
                            images.append(self._to_nodeimage(templ, self,
                                                             get_href(repo,
                                                                      'edit')))

        return images
Exemple #25
0
    def test_get_href(self):
        xml = '''
<datacenter>
        <link href="http://10.60.12.7:80/api/admin/datacenters/2"
        type="application/vnd.abiquo.datacenter+xml" rel="edit1"/>
        <link href="http://10.60.12.7:80/ponies/bar/foo/api/admin/datacenters/3"
        type="application/vnd.abiquo.datacenter+xml" rel="edit2"/>
        <link href="http://vdcbridge.interoute.com:80/jclouds/apiouds/api/admin/enterprises/1234"
        type="application/vnd.abiquo.datacenter+xml" rel="edit3"/>
</datacenter>
'''

        elem = ET.XML(xml)

        href = get_href(element=elem, rel='edit1')
        self.assertEqual(href, '/admin/datacenters/2')
        href = get_href(element=elem, rel='edit2')
        self.assertEqual(href, '/admin/datacenters/3')
        href = get_href(element=elem, rel='edit3')
        self.assertEqual(href, '/admin/enterprises/1234')
Exemple #26
0
    def test_get_href(self):
        xml = '''
<datacenter>
        <link href="http://10.60.12.7:80/api/admin/datacenters/2"
        type="application/vnd.abiquo.datacenter+xml" rel="edit1"/>
        <link href="http://10.60.12.7:80/ponies/bar/foo/api/admin/datacenters/3"
        type="application/vnd.abiquo.datacenter+xml" rel="edit2"/>
        <link href="http://vdcbridge.interoute.com:80/jclouds/apiouds/api/admin/enterprises/1234"
        type="application/vnd.abiquo.datacenter+xml" rel="edit3"/>
</datacenter>
'''

        elem = ET.XML(xml)

        href = get_href(element=elem, rel='edit1')
        self.assertEqual(href, '/admin/datacenters/2')
        href = get_href(element=elem, rel='edit2')
        self.assertEqual(href, '/admin/datacenters/3')
        href = get_href(element=elem, rel='edit3')
        self.assertEqual(href, '/admin/enterprises/1234')
Exemple #27
0
    def ex_create_group(self, name, location=None):
        """
        Create an empty group.

        You can specify the location as well.

        :param     group:     name of the group (required)
        :type      group:     ``str``

        :param     location: location were to create the group
        :type      location: :class:`NodeLocation`

        :returns:            the created group
        :rtype:              :class:`NodeGroup`
        """
        # prepare the element
        vapp = ET.Element('virtualAppliance')
        vapp_name = ET.SubElement(vapp, 'name')
        vapp_name.text = name

        if location is None:
            location = self.list_locations()[0]
        elif location not in self.list_locations():
            raise LibcloudError('Location does not exist')

        link_vdc = self.connection.cache['locations'][location]
        hdr_vdc = {'Accept': self.VDC_MIME_TYPE}
        e_vdc = self.connection.request(link_vdc, headers=hdr_vdc).object

        creation_link = get_href(e_vdc, 'virtualappliances')
        headers = {'Accept': self.VAPP_MIME_TYPE,
                   'Content-type': self.VAPP_MIME_TYPE}
        vapp = self.connection.request(creation_link, data=tostring(vapp),
                                       headers=headers, method='POST').object

        uri_vapp = get_href(vapp, 'edit')

        return NodeGroup(self, vapp.findtext('name'),
                         uri=uri_vapp)
Exemple #28
0
    def ex_create_group(self, name, location=None):
        """
        Create an empty group.

        You can specify the location as well.

        @param     name:     name of the group (required)
        @type      name:     C{str}

        @param     location: location were to create the group
        @type      location: L{NodeLocation}

        @returns:            the created group
        @rtype:              L{NodeGroup}
        """
        # prepare the element
        vapp = ET.Element('virtualAppliance')
        vapp_name = ET.SubElement(vapp, 'name')
        vapp_name.text = name

        if location is None:
            location = self.list_locations()[0]
        elif not location in self.list_locations():
            raise LibcloudError('Location does not exist')

        link_vdc = self.connection.context['locations'][location]
        e_vdc = self.connection.request(link_vdc).object

        creation_link = get_href(e_vdc, 'virtualappliances')
        headers = {'Content-type': self.VAPP_MIME_TYPE}
        vapp = self.connection.request(creation_link,
                                       data=tostring(vapp),
                                       headers=headers,
                                       method='POST').object

        uri_vapp = get_href(vapp, 'edit')

        return NodeGroup(self, vapp.findtext('name'), uri=uri_vapp)
Exemple #29
0
    def ex_create_group(self, name, location=None):
        """
        Create an empty group.

        You can specify the location as well.

        @param     name:     name of the group (required)
        @type      name:     C{str}

        @param     location: location were to create the group
        @type      location: L{NodeLocation}

        @returns:            the created group
        @rtype:              L{NodeGroup}
        """
        # prepare the element
        vapp = ET.Element('virtualAppliance')
        vapp_name = ET.SubElement(vapp, 'name')
        vapp_name.text = name

        if location is None:
            location = self.list_locations()[0]
        elif not location in self.list_locations():
            raise LibcloudError('Location does not exist')

        link_vdc = self.connection.context['locations'][location]
        e_vdc = self.connection.request(link_vdc).object

        creation_link = get_href(e_vdc, 'virtualappliances')
        headers = {'Content-type': self.VAPP_MIME_TYPE}
        vapp = self.connection.request(creation_link, data=tostring(vapp),
                                       headers=headers, method='POST').object

        uri_vapp = get_href(vapp, 'edit')

        return NodeGroup(self, vapp.findtext('name'),
                         uri=uri_vapp)
Exemple #30
0
    def ex_run_node(self, node):
        """
        Runs a node

        Here there is a bit difference between Abiquo states and libcloud
        states, so this method is created to have better compatibility. In
        libcloud, if the node is not running, then it does not exist (avoiding
        UNKNOWN and temporal states). In Abiquo, you can define a node, and
        then deploy it.

        If the node is in :class:`NodeState.TERMINATED` libcloud's state and in
        'NOT_DEPLOYED' Abiquo state, there is a way to run and recover it
        for libcloud using this method. There is no way to reach this state
        if you are using only libcloud, but you may have used another Abiquo
        client and now you want to recover your node to be used by libcloud.

        :param node: The node to run
        :type node: :class:`Node`

        :return: The node itself, but with the new state
        :rtype: :class:`Node`
        """
        # Refresh node state
        e_vm = self.connection.request(node.extra['uri_id']).object
        state = e_vm.findtext('state')

        if state != 'NOT_ALLOCATED':
            raise LibcloudError('Invalid Node state', self)

        # --------------------------------------------------------
        #     Deploy the Node
        # --------------------------------------------------------
        self._deploy_remote(e_vm)

        # --------------------------------------------------------
        #     Retrieve it again, to get some schedule-defined
        #     values.
        # --------------------------------------------------------
        edit_vm = get_href(e_vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}
        e_vm = self.connection.request(edit_vm, headers=headers).object
        return self._to_node(e_vm, self)
Exemple #31
0
    def ex_run_node(self, node):
        """
        Runs a node

        Here there is a bit difference between Abiquo states and libcloud
        states, so this method is created to have better compatibility. In
        libcloud, if the node is not running, then it does not exist (avoiding
        UNKNOWN and temporal states). In Abiquo, you can define a node, and
        then deploy it.

        If the node is in :class:`NodeState.TERMINATED` libcloud's state and in
        'NOT_DEPLOYED' Abiquo state, there is a way to run and recover it
        for libcloud using this method. There is no way to reach this state
        if you are using only libcloud, but you may have used another Abiquo
        client and now you want to recover your node to be used by libcloud.

        :param node: The node to run
        :type node: :class:`Node`

        :return: The node itself, but with the new state
        :rtype: :class:`Node`
        """
        # Refresh node state
        e_vm = self.connection.request(node.extra['uri_id']).object
        state = e_vm.findtext('state')

        if state != 'NOT_ALLOCATED':
            raise LibcloudError('Invalid Node state', self)

        # --------------------------------------------------------
        #     Deploy the Node
        # --------------------------------------------------------
        self._deploy_remote(e_vm)

        # --------------------------------------------------------
        #     Retrieve it again, to get some schedule-defined
        #     values.
        # --------------------------------------------------------
        edit_vm = get_href(e_vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}
        e_vm = self.connection.request(edit_vm, headers=headers).object
        return self._to_node(e_vm, self)
Exemple #32
0
    def _deploy_remote(self, e_vm):
        """
        Asynchronous call to create the node.
        """
        # --------------------------------------------------------
        #     Deploy the Node
        # --------------------------------------------------------
        # prepare the element that forces the deploy
        vm_task = ET.Element('virtualmachinetask')
        force_deploy = ET.SubElement(vm_task, 'forceEnterpriseSoftLimits')
        force_deploy.text = 'True'

        # Prepare the headers
        headers = {'Content-type': self.VM_TASK_MIME_TYPE}
        link_deploy = get_href(e_vm, 'deploy')
        res = self.connection.async_request(action=link_deploy, method='POST',
                                            data=tostring(vm_task),
                                            headers=headers)
        if not res.async_success():
            raise LibcloudError('Could not run the node', self)
Exemple #33
0
    def _deploy_remote(self, e_vm):
        """
        Asynchronous call to create the node.
        """
        # --------------------------------------------------------
        #     Deploy the Node
        # --------------------------------------------------------
        # prepare the element that forces the deploy
        vm_task = ET.Element('virtualmachinetask')
        force_deploy = ET.SubElement(vm_task, 'forceEnterpriseSoftLimits')
        force_deploy.text = 'True'

        # Prepare the headers
        headers = {'Content-type': self.VM_TASK_MIME_TYPE}
        link_deploy = get_href(e_vm, 'deploy')
        res = self.connection.async_request(action=link_deploy, method='POST',
                                            data=tostring(vm_task),
                                            headers=headers)
        if not res.async_success():
            raise LibcloudError('Could not run the node', self)
Exemple #34
0
    def _define_create_node_node(self,
                                 group,
                                 name=None,
                                 size=None,
                                 image=None):
        """
        Defines the node before to create.

        In Abiquo, you first need to 'register' or 'define' the node in
        the API before to create it into the target hypervisor.
        """
        vm = ET.Element("virtualMachine")
        if name:
            vmname = ET.SubElement(vm, "label")
            vmname.text = name
        attrib = {
            "type": self.VMTPL_MIME_TYPE,
            "rel": "virtualmachinetemplate",
            "href": image.extra["url"],
        }
        ET.SubElement(vm, "link", attrib=attrib)
        headers = {
            "Accept": self.NODE_MIME_TYPE,
            "Content-type": self.NODE_MIME_TYPE
        }

        if size:
            # Override the 'NodeSize' data
            ram = ET.SubElement(vm, "ram")
            ram.text = str(size.ram)

        # Create the virtual machine
        nodes_link = group.uri + "/virtualmachines"
        vm = self.connection.request(nodes_link,
                                     data=tostring(vm),
                                     headers=headers,
                                     method="POST").object
        edit_vm = get_href(vm, "edit")
        headers = {"Accept": self.NODE_MIME_TYPE}

        return self.connection.request(edit_vm, headers=headers).object
Exemple #35
0
    def _define_create_node_node(self,
                                 group,
                                 name=None,
                                 size=None,
                                 image=None):
        """
        Defines the node before to create.

        In Abiquo, you first need to 'register' or 'define' the node in
        the API before to create it into the target hypervisor.
        """
        vm = ET.Element('virtualMachine')
        if name:
            vmname = ET.SubElement(vm, 'label')
            vmname.text = name
        attrib = {
            'type': self.VMTPL_MIME_TYPE,
            'rel': 'virtualmachinetemplate',
            'href': image.extra['url']
        }
        ET.SubElement(vm, 'link', attrib=attrib)
        headers = {
            'Accept': self.NODE_MIME_TYPE,
            'Content-type': self.NODE_MIME_TYPE
        }

        if size:
            # Override the 'NodeSize' data
            ram = ET.SubElement(vm, 'ram')
            ram.text = str(size.ram)

        # Create the virtual machine
        nodes_link = group.uri + '/virtualmachines'
        vm = self.connection.request(nodes_link,
                                     data=tostring(vm),
                                     headers=headers,
                                     method='POST').object
        edit_vm = get_href(vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}

        return self.connection.request(edit_vm, headers=headers).object
Exemple #36
0
    def _deploy_remote(self, e_vm):
        """
        Asynchronous call to create the node.
        """
        # --------------------------------------------------------
        #     Deploy the Node
        # --------------------------------------------------------
        # prepare the element that forces the deploy
        vm_task = ET.Element("virtualmachinetask")
        force_deploy = ET.SubElement(vm_task, "forceEnterpriseSoftLimits")
        force_deploy.text = "True"

        # Prepare the headers
        headers = {
            "Accept": self.AR_MIME_TYPE,
            "Content-type": self.VM_TASK_MIME_TYPE
        }
        link_deploy = get_href(e_vm, "deploy")
        res = self.connection.async_request(action=link_deploy,
                                            method="POST",
                                            data=tostring(vm_task),
                                            headers=headers)
        if not res.async_success():  # pylint: disable=maybe-no-member
            raise LibcloudError("Could not run the node", self)
Exemple #37
0
    def create_node(self, **kwargs):
        """
        Create a new node instance in Abiquo

        All the :class:`Node`s need to be defined inside a VirtualAppliance
        (called :class:`NodeGroup` here). If there is no group name defined,
        'libcloud' name will be used instead.

        This method wraps these Abiquo actions:

            1. Create a group if it does not exist.
            2. Register a new node in the group.
            3. Deploy the node and boot it.
            4. Retrieves it again to get schedule-time attributes (such as ips
               and vnc ports).

        The rest of the driver methods has been created in a way that, if any
        of these actions fail, the user can not reach an inconsistent state

        :keyword    name:   The name for this new node (required)
        :type       name:   ``str``

        :keyword    size:   The size of resources allocated to this node.
        :type       size:   :class:`NodeSize`

        :keyword    image:  OS Image to boot on node. (required)
        :type       image:  :class:`NodeImage`

        :keyword    location: Which data center to create a node in. If empty,
                              undefined behavoir will be selected. (optional)
        :type       location: :class:`NodeLocation`

        :keyword   group_name:  Which group this node belongs to. If empty,
                                 it will be created into 'libcloud' group. If
                                 it does not found any group in the target
                                 location (random location if you have not set
                                 the parameter), then it will create a new
                                 group with this name.
        :type     group_name:  c{str}

        :return:               The newly created node.
        :rtype:                :class:`Node`
        """
        # Define the location
        # To be clear:
        #     'xml_loc' is the xml element we navigate into (we need links)
        #     'loc' is the :class:`NodeLocation` entity
        xml_loc, loc = self._define_create_node_location(**kwargs)

        # Define the Group
        group = self._define_create_node_group(xml_loc, loc, **kwargs)

        # Register the Node
        vm = self._define_create_node_node(group, **kwargs)

        # Execute the 'create' in hypervisor action
        self._deploy_remote(vm)

        # Retrieve it again, to get some schedule-time defined values
        edit_vm = get_href(vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}
        vm = self.connection.request(edit_vm, headers=headers).object
        return self._to_node(vm, self)
Exemple #38
0
    def create_node(self, **kwargs):
        """
        Create a new node instance in Abiquo

        All the :class:`Node`s need to be defined inside a VirtualAppliance
        (called :class:`NodeGroup` here). If there is no group name defined,
        'libcloud' name will be used instead.

        This method wraps these Abiquo actions:

            1. Create a group if it does not exist.
            2. Register a new node in the group.
            3. Deploy the node and boot it.
            4. Retrieves it again to get schedule-time attributes (such as ips
               and vnc ports).

        The rest of the driver methods has been created in a way that, if any
        of these actions fail, the user can not reach an inconsistent state

        :keyword    name:   The name for this new node (required)
        :type       name:   ``str``

        :keyword    size:   The size of resources allocated to this node.
        :type       size:   :class:`NodeSize`

        :keyword    image:  OS Image to boot on node. (required)
        :type       image:  :class:`NodeImage`

        :keyword    location: Which data center to create a node in. If empty,
                              undefined behavior will be selected. (optional)
        :type       location: :class:`NodeLocation`

        :keyword   group_name:  Which group this node belongs to. If empty,
                                 it will be created into 'libcloud' group. If
                                 it does not found any group in the target
                                 location (random location if you have not set
                                 the parameter), then it will create a new
                                 group with this name.
        :type     group_name:  c{str}

        :return:               The newly created node.
        :rtype:                :class:`Node`
        """
        # Define the location
        # To be clear:
        #     'xml_loc' is the xml element we navigate into (we need links)
        #     'loc' is the :class:`NodeLocation` entity
        xml_loc, loc = self._define_create_node_location(**kwargs)

        # Define the Group
        group = self._define_create_node_group(xml_loc, loc, **kwargs)

        # Register the Node
        vm = self._define_create_node_node(group, **kwargs)

        # Execute the 'create' in hypervisor action
        self._deploy_remote(vm)

        # Retrieve it again, to get some schedule-time defined values
        edit_vm = get_href(vm, 'edit')
        headers = {'Accept': self.NODE_MIME_TYPE}
        vm = self.connection.request(edit_vm, headers=headers).object
        return self._to_node(vm, self)