From: Frank Brehm Date: Tue, 8 Mar 2016 21:37:44 +0000 (+0100) Subject: Initial X-Git-Url: https://git.uhu-banane.org/?a=commitdiff_plain;ds=sidebyside;p=my-stuff%2Fpb-create-vm.git Initial --- diff --git a/bin/create-vm b/bin/create-vm new file mode 100755 index 0000000..4e6a2b2 --- /dev/null +++ b/bin/create-vm @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +@author: Frank Brehm +@contact: frank@brehm-online.com +@copyright: © 2010 - 2016 by Frank Brehm, Berlin +@license: GPL3 +@summary: script for automated creation of my necessary VMs. +""" + +import sys +import os +import logging + +if __name__ == "__main__": + libdir = os.path.join(os.path.dirname(sys.argv[0]), '..', 'lib') + libdir = os.path.relpath(os.path.abspath(libdir)) + sys.path.insert(0, libdir) + +from vm_create_app import VmCreateApp + +MY_BASENAME = os.path.basename(__file__) +LOG = logging.getLogger(MY_BASENAME) + +__version__ = '0.1.0' + +# ============================================================================= + +if __name__ == "__main__": + + app = VmCreateApp() + LOG.debug("Starting the %s application.", app.__class__.__name__) + app() + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 diff --git a/lib/vm_create_app.py b/lib/vm_create_app.py new file mode 100644 index 0000000..5c89063 --- /dev/null +++ b/lib/vm_create_app.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@author: Frank Brehm +@contact: frank@brehm-online.com +@copyright: © 2010 - 2016 by Frank Brehm, Berlin +@license: GPL3 +@summary: application module for automated creation of my VM +""" + +import sys +import os +import logging +import uuid +import re + +import requests + +from pb_logging.colored import ColoredFormatter + +from pb_base.common import pp, to_bool +from pb_base.common import to_str_or_bust as to_str + +from pb_base.app import PbApplicationError +from pb_base.app import PbApplication + +from profitbricks.client import ProfitBricksService +from profitbricks.client import Datacenter +from profitbricks.client import Volume + +LOG = logging.getLogger(__name__) + +PB_URL = "https://api.profitbricks.com/rest/v2" +PB_USER = 'frank@brehm-online.com' +PB_PWD = 'up2UdLCE' + +PB_LOC = 'de/fra' + +DC_NAME = 'DC Uhu Fra' + +__version__ = '0.1.0' + +requests.packages.urllib3.disable_warnings() + + +# ============================================================================= +class VmCreateApp(PbApplication): + """ + Application class for creating my needed VMs at ProfitBricks. + """ + + # ------------------------------------------------------------------------- + def __init__( + self, verbose=0, version=__version__, *arg, **kwargs): + + desc = "Creates automated all my necessary VMs." + + self.image_uuid = None + self.image_name = None + self.image_size_mb = None + self.location = None + self.dc_id = None + self.dc_name = None + self.dc_desc = None + self.simulate = False + + self.template_image = None + + self.api_url = PB_URL + self.api_user = PB_USER + self.api_passwd = PB_PWD + + super(VmCreateApp, self).__init__( + usage=None, + description=desc, + verbose=verbose, + version=version, + *arg, **kwargs + ) + + self.pb_client = None + + self.post_init() + self.initialized = True + + if self.verbose > 2: + LOG.debug("%s object:\n%s", self.__class__.__name__, pp(self.as_dict(True))) + + # ------------------------------------------------------------------------- + def post_init(self): + """ + Method to execute before calling run(). Here could be done some + finishing actions after reading in commandline parameters, + configuration a.s.o. + + This method could be overwritten by descendant classes, these + methhods should allways include a call to post_init() of the + parent class. + + """ + + super(VmCreateApp, self).post_init() + self.initialized = False + + LOG.debug("Initializing ProfitBricksService object ...") + self.pb_client = ProfitBricksService( + username=self.api_user, + password=self.api_passwd, + host_base=self.api_url, + host_cert=None, + ssl_verify=False, + ) + + # ------------------------------------------------------------------------- + def get_request_status(self, request_id): + + response = self.pb_client.get_request(str(request_id), status=True) + if self.verbose > 3: + LOG.debug("Response on getting request status:\n%s", pp(response)) + if not 'metadata' in response: + LOG.error("Got not metadata in response of getting request status.") + return None + + if not 'status' in response['metadata']: + LOG.error("Got no status in metadata in response of getting request status.") + return None + + status = to_str(response['metadata']['status']) + message = to_str(response['metadata']['message']) + + return (status, message) + + # ------------------------------------------------------------------------- + def _select_install_image(self): + + pref_location = PB_LOC + re_debian = re.compile(r'debian', re.IGNORECASE) + + images = self.pb_client.list_images() + if not images: + msg = "No images for creating storage volumes found." + LOG.error(msg) + + img_list = [] + for entry in images['items']: + + img_type = to_str(entry['properties']['imageType']) + if img_type.lower() != 'hdd': + continue + + lic_type = to_str(entry['properties']['licenceType']) + if lic_type.lower() == 'windows': + continue + + loc = to_str(entry['properties']['location']) + if loc.lower() != pref_location.lower(): + continue + + public = to_bool(entry['properties']['public']) + if not public: + continue + + img_name = to_str(entry['properties']['name']) + + if not re_debian.search(img_name): + continue + + img = { + 'uuid': uuid.UUID(entry['id']), + 'name': img_name, + 'size_gb': entry['properties']['size'], + 'type': img_type, + 'licence_type': lic_type.lower(), + 'location': loc, + } + + img_list.append(img) + + if self.verbose > 3: + LOG.debug("Got image list:\n" + pp(img_list)) + + img_names = [] + for img in sorted(img_list, key=lambda x: x['name'].lower()): + img_names.append(img['name']) + + if self.verbose: + LOG.debug("Available public image names:\n%s", pp(img_names)) + + if not img_list: + msg = "No usable images for creating storage volumes found." + self.exit(5, msg) + + self.template_image = img_list[-1] + LOG.info('Used template image for installation:\n%s', pp(self.template_image)) + + + # ------------------------------------------------------------------------- + def _select_or_create_datacenter(self): + + self.dc_id = None + + response = self.pb_client.list_datacenters() + if self.verbose > 2: + LOG.debug("Response on list datacenters:\n%s", pp(response)) + + pref_location = PB_LOC + + # ------------------------------------------------------------------------- + def _run(self): + """The underlaying startpoint of the application.""" + + LOG.info( + "Starting as user %r (%r) ...", + self.api_user, self.api_url) + + self._select_or_create_datacenter() + self._select_install_image() + + +# ============================================================================= + +if __name__ == "__main__": + + pass + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4