provisioner.py 4.64 KB
Newer Older
1 2 3
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
import logging
4

5 6 7 8
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

from kamaki.clients import astakos, cyclades
9 10 11 12
from kamaki.clients import ClientError
from kamaki.clients.utils import https
from kamaki.cli.config import Config as KamakiConfig

13
# TODO: remove this and actually use ssl cert files
14 15 16 17
https.patch_ignore_ssl()

import argparse

18
storage_templates = ['drdb', 'ext_vlmc']
19 20 21 22


class Provisioner:
    """
23
        provisions virtual machines on ~okeanos
24 25
    """

26
    def __init__(self, cloud_name):
27 28

        # Load .kamakirc configuration
29
        logger.info("Retrieving .kamakirc configuration")
30
        self.config = KamakiConfig()
31 32 33 34 35
        cloud_section = self.config._sections['cloud'].get(cloud_name)
        if not cloud_section:
            message = "Cloud '%s' was not found in you .kamakirc configuration file. " \
                      "Currently you have availablie in your configuration these clouds: %s"
            raise KeyError(message % (cloud_name, self.config._sections['cloud'].keys()))
36 37 38 39

        # Get the authentication url and token
        auth_url, auth_token = cloud_section['url'], cloud_section['token']

40
        logger.info("Initiating Astakos Client")
41 42
        self.astakos = astakos.AstakosClient(auth_url, auth_token)

43 44
        logger.info("Retrieving cyclades endpoint url")
        compute_url = self.astakos.get_endpoint_url(
45
            cyclades.CycladesComputeClient.service_type)
46 47
        logger.info("Initiating Cyclades client")
        self.cyclades = cyclades.CycladesComputeClient(compute_url, auth_token)
48

49
    def find_flavor(self, **kwargs):
50 51
        """

52
        :param kwargs: should contains the keys that specify the specs
53
        :return: first flavor objects that matches the specs criteria
54
        """
55 56 57 58 59

        # Set all the default parameters
        kwargs.setdefault("vcpus", 1)
        kwargs.setdefault("ram", 1024)
        kwargs.setdefault("disk", 40)
60
        logger.info("Retrieving flavor")
61
        for flavor in self.cyclades.list_flavors(detail=True):
62 63
            if all([kwargs[key] == flavor[key] \
                    for key in set(flavor.keys()).intersection(kwargs.keys())]):
64 65 66
                return flavor
        return None

67
    def find_image(self, **kwargs):
68 69 70 71 72
        """
        :param image_name: Name of the image to filter by
        :param kwargs:
        :return: first image object that matches the name criteria
        """
73
        image_name = kwargs['image_name']
74 75

        logger.info("Retrieving image")
76
        for image in self.cyclades.list_images(detail=True):
77
            if image_name in image['name']:
78 79 80 81
                return image
        return None

    def find_project_id(self, **kwargs):
82 83 84 85
        """
        :param kwargs: name, state, owner and mode to filter project by
        :return: first project_id that matches the project name
        """
86
        filter = {
87 88 89 90
            'name': kwargs.get("project_name"),
            'state': kwargs.get("project_state"),
            'owner': kwargs.get("project_owner"),
            'mode': kwargs.get("project_mode"),
91
        }
92
        logger.info("Retrieving project")
93 94 95
        return self.astakos.get_projects(**filter)[0]

    def create_vm(self, vm_name=None, **kwargs):
96 97 98 99 100
        """
        :param vm_name: Name of the virtual machine to create
        :param kwargs: passed to the functions called for detail options
        :return:
        """
101 102 103 104
        flavor_id = self.find_flavor(**kwargs)['id']
        image_id = self.find_image(**kwargs)['id']
        project_id = self.find_project_id(**kwargs)['id']
        try:
105
            okeanos_response = self.cyclades.create_server(name=vm_name, flavor_id=flavor_id,
106 107 108
                                                           image_id=image_id,
                                                           project_id=project_id,
                                                           networks=[], personality=[])
109
        except ClientError as ex:
110 111
            raise ex
        return okeanos_response
112 113 114 115 116


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Okeanos VM provisioning")
    parser.add_argument('--cloud', type=str, dest="cloud", default="lambda")
117 118 119
    parser.add_argument('--project-name', type=str, dest="project_name",
                        default="lambda.grnet.gr")
    parser.add_argument('--name', type=str, dest='name', default="to mikro debian sto livadi")
120 121

    args = parser.parse_args()
122 123

    provisioner = Provisioner(cloud_name=args.cloud)
Avraam Tsantekidis's avatar
Avraam Tsantekidis committed
124 125
    print(provisioner.create_vm(vm_name=args.name, project_name=args.project_name,
                            image_name="debian"))