Update version.py and ChangeLog for 0.6.1
[snf-image-creator] / image_creator / dialog_util.py
index f7add02..af5e425 100644 (file)
@@ -1,5 +1,5 @@
-#!/usr/bin/env python
-
+# -*- coding: utf-8 -*-
+#
 # Copyright 2012 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
+"""Module providing useful functions for the dialog-based version of
+snf-image-creator.
+"""
+
 import os
+import re
+import json
 from image_creator.output.dialog import GaugeOutput
 from image_creator.util import MD5
+from image_creator.kamaki_wrapper import Kamaki
 
 SMALL_WIDTH = 60
 WIDTH = 70
 
 
 def update_background_title(session):
+    """Update the backgroud title of the dialog page"""
     d = session['dialog']
     disk = session['disk']
     image = session['image']
@@ -60,28 +68,35 @@ def update_background_title(session):
 
 
 def confirm_exit(d, msg=''):
+    """Ask the user to confirm when exiting the program"""
     return not d.yesno("%s Do you want to exit?" % msg, width=SMALL_WIDTH)
 
 
 def confirm_reset(d):
+    """Ask the user to confirm a reset action"""
     return not d.yesno("Are you sure you want to reset everything?",
                        width=SMALL_WIDTH, defaultno=1)
 
 
 class Reset(Exception):
+    """Exception used to reset the program"""
     pass
 
 
 def extract_metadata_string(session):
-    metadata = ['%s=%s' % (k, v) for (k, v) in session['metadata'].items()]
-
+    """Convert image metadata to text"""
+    metadata = {}
+    metadata.update(session['metadata'])
     if 'task_metadata' in session:
-        metadata.extend("%s=yes" % m for m in session['task_metadata'])
+        for key in session['task_metadata']:
+            metadata[key] = 'yes'
 
-    return '\n'.join(metadata) + '\n'
+    return unicode(json.dumps({'properties': metadata,
+                               'disk-format': 'diskdump'}, ensure_ascii=False))
 
 
 def extract_image(session):
+    """Dump the image to a local file"""
     d = session['dialog']
     dir = os.getcwd()
     while 1:
@@ -140,13 +155,13 @@ def extract_image(session):
                 image.dump(path)
 
                 # Extract metadata file
-                out.output("Extracting metadata file...")
+                out.output("Extracting metadata file ...")
                 with open('%s.meta' % path, 'w') as f:
                     f.write(extract_metadata_string(session))
                 out.success('done')
 
                 # Extract md5sum file
-                out.output("Extracting md5sum file...")
+                out.output("Extracting md5sum file ...")
                 md5str = "%s %s\n" % (session['checksum'], name)
                 with open('%s.md5sum' % path, 'w') as f:
                     f.write(md5str)
@@ -161,4 +176,113 @@ def extract_image(session):
 
     return True
 
+
+def _check_cloud(session, name, description, url, token):
+    """Checks if the provided info for a cloud are valid"""
+    d = session['dialog']
+    regexp = re.compile('^[~@#$:\-\w]+$')
+
+    if not re.match(regexp, name):
+        d.msgbox("Allowed characters for name: a-zA-Z0-9_~@#$:-", width=WIDTH)
+        return False
+
+    if len(url) == 0:
+        d.msgbox("Url cannot be empty!", width=WIDTH)
+        return False
+
+    if len(token) == 0:
+        d.msgbox("Token cannot be empty!", width=WIDTH)
+        return False
+
+    if Kamaki.create_account(url, token) is None:
+        d.msgbox("The cloud info you provided is not valid. Please check the "
+                 "Authentication URL and the token values again!", width=WIDTH)
+        return False
+
+    return True
+
+
+def add_cloud(session):
+    """Add a new cloud account"""
+
+    d = session['dialog']
+
+    name = ""
+    description = ""
+    url = ""
+    token = ""
+
+    while 1:
+        fields = [
+            ("Name:", name, 60),
+            ("Description (optional): ", description, 80),
+            ("Authentication URL: ", url, 200),
+            ("Token:", token, 100)]
+
+        (code, output) = d.form("Add a new cloud account:", height=13,
+                                width=WIDTH, form_height=4, fields=fields)
+
+        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
+            return False
+
+        name, description, url, token = output
+
+        name = name.strip()
+        description = description.strip()
+        url = url.strip()
+        token = token.strip()
+
+        if _check_cloud(session, name, description, url, token):
+            if name in Kamaki.get_clouds().keys():
+                d.msgbox("A cloud with name `%s' already exists. If you want "
+                         "to edit the existing cloud account, use the edit "
+                         "menu." % name, width=WIDTH)
+            else:
+                Kamaki.save_cloud(name, url, token, description)
+                break
+
+        continue
+
+    return True
+
+
+def edit_cloud(session, name):
+    """Edit a cloud account"""
+
+    info = Kamaki.get_cloud_by_name(name)
+
+    assert info, "Cloud: `%s' does not exist" % name
+
+    description = info['description'] if 'description' in info else ""
+    url = info['url'] if 'url' in info else ""
+    token = info['token'] if 'token' in info else ""
+
+    d = session['dialog']
+
+    while 1:
+        fields = [
+            ("Description (optional): ", description, 80),
+            ("Authentication URL: ", url, 200),
+            ("Token:", token, 100)]
+
+        (code, output) = d.form("Edit cloud account: `%s'" % name, height=13,
+                                width=WIDTH, form_height=3, fields=fields)
+
+        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
+            return False
+
+        description, url, token = output
+
+        description = description.strip()
+        url = url.strip()
+        token = token.strip()
+
+        if _check_cloud(session, name, description, url, token):
+            Kamaki.save_cloud(name, url, token, description)
+            break
+
+        continue
+
+    return True
+
 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :