commit 49c07ce389257085642c76aa3318b80076e18bd6
Author: Nikos Skalkotos <skalkoto@grnet.gr>
Date:   Tue Jun 18 16:27:05 2013 +0300

    Comply with kamaki 0.9
    
     * Change the authentication everywhere to use clouds
       (authentication URL and token pairs)
     * Add menu entries to manage clouds
     * Add an extra -a option in snf-image-creator to allow the user to
       specify authentication URLs

diff --git a/image_creator/dialog_menu.py b/image_creator/dialog_menu.py
index 5b5526c..858dc19 100644
--- a/image_creator/dialog_menu.py
+++ b/image_creator/dialog_menu.py
@@ -48,7 +48,7 @@ from image_creator.kamaki_wrapper import Kamaki, ClientError
 from image_creator.help import get_help_file
 from image_creator.dialog_util import SMALL_WIDTH, WIDTH, \
     update_background_title, confirm_reset, confirm_exit, Reset, \
-    extract_image, extract_metadata_string
+    extract_image, extract_metadata_string, add_cloud, edit_cloud
 
 CONFIGURATION_TASKS = [
     ("Partition table manipulation", ["FixPartitionTable"],
@@ -119,8 +119,8 @@ def upload_image(session):
     size = image.size
 
     if "account" not in session:
-        d.msgbox("You need to provide your ~okeanos credentials before you "
-                 "can upload images to pithos+", width=SMALL_WIDTH)
+        d.msgbox("You need to select a valid cloud before you can upload "
+                 "images to pithos+", width=SMALL_WIDTH)
         return False
 
     while 1:
@@ -204,7 +204,7 @@ def register_image(session):
     is_public = False
 
     if "account" not in session:
-        d.msgbox("You need to provide your ~okeanos credentians before you "
+        d.msgbox("You need to select a valid cloud before you "
                  "can register an images with cyclades", width=SMALL_WIDTH)
         return False
 
@@ -277,25 +277,102 @@ def register_image(session):
     return True
 
 
+def modify_clouds(session):
+    """Modify existing cloud accounts"""
+    d = session['dialog']
+
+    while 1:
+        clouds = Kamaki.get_clouds()
+        if not len(clouds):
+            if not add_cloud(session):
+                break
+            continue
+
+        choices = []
+        for (name, cloud) in clouds.items():
+            descr = cloud['description'] if 'description' in cloud else ''
+            choices.append((name, descr))
+
+        (code, choice) = d.menu(
+            "In this menu you can edit existing cloud accounts or add new "
+            " ones. Press <Edit> to edit an existing account or <Add> to add "
+            " a new one. Press <Back> or hit <ESC> when done.", height=18,
+            width=WIDTH, choices=choices, menu_height=10, ok_label="Edit",
+            extra_button=1, extra_label="Add", cancel="Back", help_button=1,
+            title="Clouds")
+
+        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
+            return True
+        elif code == d.DIALOG_OK:  # Edit button
+            edit_cloud(session, choice)
+        elif code == d.DIALOG_EXTRA:  # Add button
+            add_cloud(session)
+
+
+def delete_clouds(session):
+    """Delete existing cloud accounts"""
+    d = session['dialog']
+
+    choices = []
+    for (name, cloud) in Kamaki.get_clouds().items():
+        descr = cloud['description'] if 'description' in cloud else ''
+        choices.append((name, descr, 0))
+
+    if len(choices) == 0:
+        d.msgbox("No available clouds to delete!", width=SMALL_WIDTH)
+        return True
+
+    (code, to_delete) = d.checklist("Choose which cloud accounts to delete:",
+                                    choices=choices, width=WIDTH)
+
+    if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
+        return False
+
+    if not len(to_delete):
+        d.msgbox("Nothing selected!", width=SMALL_WIDTH)
+        return False
+
+    if not d.yesno("Are you sure you want to remove the selected cloud "
+                   "accounts?", width=WIDTH, defaultno=1):
+        for i in to_delete:
+            Kamaki.remove_cloud(i)
+            if 'cloud' in session and session['cloud'] == i:
+                del session['cloud']
+                if 'account' in session:
+                    del session['account']
+    else:
+        return False
+
+    d.msgbox("%d cloud accounts were deleted." % len(to_delete),
+             width=SMALL_WIDTH)
+    return True
+
+
 def kamaki_menu(session):
     """Show kamaki related actions"""
     d = session['dialog']
-    default_item = "Account"
+    default_item = "Cloud"
 
-    if 'account' not in session:
-        token = Kamaki.get_token()
-        if token:
-            session['account'] = Kamaki.get_account(token)
+    if 'cloud' not in session:
+        cloud = Kamaki.get_default_cloud_name()
+        if cloud:
+            session['cloud'] = cloud
+            session['account'] = Kamaki.get_account(cloud)
             if not session['account']:
                 del session['account']
-                Kamaki.save_token('')  # The token was not valid. Remove it
+        else:
+            default_item = "Add/Edit"
 
     while 1:
-        account = session["account"]['username'] if "account" in session else \
-            "<none>"
+        cloud = session["cloud"] if "cloud" in session else "<none>"
+        if 'account' not in session and 'cloud' in session:
+            cloud += " <invalid>"
+
         upload = session["upload"] if "upload" in session else "<none>"
 
-        choices = [("Account", "Change your ~okeanos account: %s" % account),
+        choices = [("Add/Edit", "Add/Edit cloud accounts"),
+                   ("Delete", "Delete existing cloud accounts"),
+                   ("Cloud", "Select cloud account to use: %s" % cloud),
                    ("Upload", "Upload image to pithos+"),
                    ("Register", "Register the image to cyclades: %s" % upload)]
 
@@ -308,26 +385,56 @@ def kamaki_menu(session):
         if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
             return False
 
-        if choice == "Account":
-            default_item = "Account"
-            (code, answer) = d.inputbox(
-                "Please provide your ~okeanos authentication token:",
-                init=session["account"]['auth_token'] if "account" in session
-                else '', width=WIDTH)
+        if choice == "Add/Edit":
+            if modify_clouds(session):
+                default_item = "Cloud"
+        elif choice == "Delete":
+            if delete_clouds(session):
+                if len(Kamaki.get_clouds()):
+                    default_item = "Cloud"
+                else:
+                    default_time = "Add/Edit"
+            else:
+                default_time = "Delete"
+        elif choice == "Cloud":
+            default_item = "Cloud"
+            clouds = Kamaki.get_clouds()
+            if not len(clouds):
+                d.msgbox("No clouds available. Please add a new cloud!",
+                         width=SMALL_WIDTH)
+                default_item = "Add/Edit"
+                continue
+
+            if 'cloud' not in session:
+                session['cloud'] = clouds.keys()[0]
+
+            choices = []
+            for name, info in clouds.items():
+                default = 1 if session['cloud'] == name else 0
+                descr = info['description'] if 'description' in info else ""
+                choices.append((name, descr, default))
+
+            (code, answer) = d.radiolist("Please select a cloud:",
+                                         width=WIDTH, choices=choices)
             if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
                 continue
-            if len(answer) == 0 and "account" in session:
-                del session["account"]
             else:
-                token = answer.strip()
-                session['account'] = Kamaki.get_account(token)
+                session['account'] = Kamaki.get_account(answer)
+
+                if session['account'] is None:  # invalid account
+                    if not d.yesno("The cloud %s' is not valid! Would you "
+                                   "like to edit it?" % answer, width=WIDTH):
+                        if edit_cloud(session, answer):
+                            session['account'] = Kamaki.get_account(answer)
+                            Kamaki.set_default_cloud(answer)
+
                 if session['account'] is not None:
-                    Kamaki.save_token(token)
+                    session['cloud'] = answer
+                    Kamaki.set_default_cloud(answer)
                     default_item = "Upload"
                 else:
                     del session['account']
-                    d.msgbox("The token you provided is not valid!",
-                             width=SMALL_WIDTH)
+                    del session['cloud']
         elif choice == "Upload":
             if upload_image(session):
                 default_item = "Register"
@@ -668,8 +775,8 @@ def main_menu(session):
 
     update_background_title(session)
 
-    choices = [("Customize", "Customize image & ~okeanos deployment options"),
-               ("Register", "Register image to ~okeanos"),
+    choices = [("Customize", "Customize image & cloud deployment options"),
+               ("Register", "Register image to a cloud"),
                ("Extract", "Dump image to local file system"),
                ("Reset", "Reset everything and start over again"),
                ("Help", "Get help for using snf-image-creator")]
