]> Frank Brehm's Git Trees - my-stuff/pb-create-vm.git/commitdiff
Initial master
authorFrank Brehm <frank@brehm-online.com>
Tue, 8 Mar 2016 21:37:44 +0000 (22:37 +0100)
committerFrank Brehm <frank@brehm-online.com>
Tue, 8 Mar 2016 21:37:44 +0000 (22:37 +0100)
bin/create-vm [new file with mode: 0755]
lib/vm_create_app.py [new file with mode: 0644]

diff --git a/bin/create-vm b/bin/create-vm
new file mode 100755 (executable)
index 0000000..4e6a2b2
--- /dev/null
@@ -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 (file)
index 0000000..5c89063
--- /dev/null
@@ -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