Commit 31160dc8 authored by Nikos Skalkotos's avatar Nikos Skalkotos

Use only the token to authenticate to synnefo

You don't need the account name. You can fetch it from astakos using
the authentication token.
parent bc9d122f
......@@ -113,16 +113,10 @@ def upload_image(session):
size = dev.size
if "account" not in session:
d.msgbox("You need to provide your ~okeanos login username before you "
d.msgbox("You need to provide your ~okeanos account before you "
"can upload images to pithos+", width=SMALL_WIDTH)
return False
if "token" not in session:
d.msgbox("You need to provide your ~okeanos account authentication "
"token before you can upload images to pithos+",
width=SMALL_WIDTH)
return False
while 1:
init = session["upload"] if "upload" in session else ''
(code, answer) = d.inputbox("Please provide a filename:", init=init,
......@@ -147,7 +141,7 @@ def upload_image(session):
md5 = MD5(out)
session['checksum'] = md5.compute(session['snapshot'], size)
kamaki = Kamaki(session['account'], session['token'], out)
kamaki = Kamaki(session['account'], out)
try:
# Upload image file
with open(session['snapshot'], 'rb') as f:
......@@ -197,12 +191,6 @@ def register_image(session):
width=SMALL_WIDTH)
return False
if "token" not in session:
d.msgbox("You need to provide your ~okeanos account authentication "
"token before you can register an images to cyclades",
width=SMALL_WIDTH)
return False
if "pithos_uri" not in session:
d.msgbox("You need to upload the image to pithos+ before you can "
"register it to cyclades", width=SMALL_WIDTH)
......@@ -233,7 +221,7 @@ def register_image(session):
try:
out.output("Registering image with Cyclades...")
try:
kamaki = Kamaki(session['account'], session['token'], out)
kamaki = Kamaki(session['account'], out)
kamaki.register(name, session['pithos_uri'], metadata)
out.success('done')
except ClientError as e:
......@@ -253,21 +241,20 @@ def kamaki_menu(session):
d = session['dialog']
default_item = "Account"
account = Kamaki.get_account()
if account:
session['account'] = account
token = Kamaki.get_token()
if token:
session['token'] = token
if 'account' not in session:
token = Kamaki.get_token()
if token:
session['account'] = Kamaki.get_account(token)
if not session['account']:
del session['account']
Kamaki.save_token('') # The token was not valid. Remove it
while 1:
account = session["account"] if "account" in session else "<none>"
token = session["token"] if "token" in session else "<none>"
account = session["account"]['username'] if "account" in session else \
"<none>"
upload = session["upload"] if "upload" in session else "<none>"
choices = [("Account", "Change your ~okeanos user id: %s" % account),
("Token", "Change your ~okeanos token: %s" % token),
choices = [("Account", "Change your ~okeanos account: %s" % account),
("Upload", "Upload image to pithos+"),
("Register", "Register the image to cyclades: %s" % upload)]
......@@ -283,31 +270,23 @@ def kamaki_menu(session):
if choice == "Account":
default_item = "Account"
(code, answer) = d.inputbox(
"Please provide your ~okeanos account user id:",
init=session["account"] if "account" in session else '',
width=WIDTH)
"Please provide your ~okeanos token:",
init=session["account"]['auth_token'] if "account" in session
else '', width=WIDTH)
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
continue
if len(answer) == 0 and "account" in session:
del session["account"]
else:
session["account"] = answer.strip()
Kamaki.save_account(session['account'])
default_item = "Token"
elif choice == "Token":
default_item = "Token"
(code, answer) = d.inputbox(
"Please provide your ~okeanos account authetication token:",
init=session["token"] if "token" in session else '',
width=WIDTH)
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
continue
if len(answer) == 0 and "token" in session:
del session["token"]
else:
session["token"] = answer.strip()
Kamaki.save_token(session['token'])
default_item = "Upload"
token = answer.strip()
session['account'] = Kamaki.get_account(token)
if session['account'] is not None:
Kamaki.save_token(token)
default_item = "Upload"
else:
del session['account']
d.msgbox("The token you provided is not valid!",
width=SMALL_WIDTH)
elif choice == "Upload":
if upload_image(session):
default_item = "Register"
......
......@@ -49,6 +49,10 @@ class WizardExit(Exception):
pass
class WizardInvalidData(Exception):
pass
class Wizard:
def __init__(self, session):
self.session = session
......@@ -65,6 +69,8 @@ class Wizard:
idx += self.pages[idx].run(self.session, idx, len(self.pages))
except WizardExit:
return False
except WizardInvalidData:
continue
if idx >= len(self.pages):
break
......@@ -125,17 +131,21 @@ class WizardInputPage(WizardPage):
self.name = name
self.message = message
self.title = kargs['title'] if 'title' in kargs else ''
self.init_value = kargs['init'] if 'init' in kargs else ''
self.allow_empty = kargs['empty'] if 'empty' in kargs else False
self.init = kargs['init'] if 'init' in kargs else ''
if 'validate' in kargs:
validate = kargs['validate']
else:
validate = lambda x: x
setattr(self, "validate", validate)
def run(self, session, index, total):
d = session['dialog']
w = session['wizard']
init = w[self.name] if self.name in w else self.init_value
while True:
(code, answer) = \
d.inputbox(self.message, init=init,
d.inputbox(self.message, init=self.init,
width=PAGE_WIDTH, ok_label="Next", cancel="Back",
title="(%d/%d) %s" % (index + 1, total, self.title))
......@@ -143,10 +153,8 @@ class WizardInputPage(WizardPage):
return self.PREV
value = answer.strip()
if len(value) == 0 and self.allow_empty is False:
d.msgbox("The value cannot be empty!", width=PAGE_WIDTH)
continue
w[self.name] = value
self.init = value
w[self.name] = self.validate(value)
break
return self.NEXT
......@@ -175,9 +183,6 @@ class WizardYesNoPage(WizardPage):
def wizard(session):
init_account = Kamaki.get_account()
if init_account is None:
init_account = ""
init_token = Kamaki.get_token()
if init_token is None:
......@@ -187,17 +192,27 @@ def wizard(session):
title="Image Name", init=session['device'].distro)
descr = WizardInputPage("ImageDescription",
"Please provide a description for the image:",
title="Image Description", empty=True,
title="Image Description",
init=session['metadata']['DESCRIPTION'] if
'DESCRIPTION' in session['metadata'] else '')
def validate_account(token):
if len(token) == 0:
d.msgbox("The token cannot be empty", width=PAGE_WIDTH)
raise WizardInvalidData
account = Kamaki.get_account(token)
if account is None:
session['dialog'].msgbox("The token you provided in not valid!",
width=PAGE_WIDTH)
raise WizardInvalidData
return account
account = WizardInputPage("account",
"Please provide your ~okeanos account user id:",
title="~okeanos account information",
init=init_account)
token = WizardInputPage("token",
"Please provide your ~okeanos account token:",
title="~okeanos account token",
init=init_token)
"Please provide your ~okeanos authentication token:",
title="~okeanos account token", init=init_token,
validate=validate_account)
msg = "All necessary information has been gathered. Confirm and Proceed."
proceed = WizardYesNoPage(msg, title="Confirmation")
......@@ -207,7 +222,6 @@ def wizard(session):
w.add_page(name)
w.add_page(descr)
w.add_page(account)
w.add_page(token)
w.add_page(proceed)
if w.run():
......@@ -227,8 +241,7 @@ def create_image(session):
wizard = session['wizard']
# Save Kamaki credentials
Kamaki.save_account(wizard['account'])
Kamaki.save_token(wizard['token'])
Kamaki.save_token(wizard['account']['auth_token'])
with_progress = OutputWthProgress(True)
out = disk.out
......@@ -262,7 +275,7 @@ def create_image(session):
out.output()
try:
out.output("Uploading image to pithos:")
kamaki = Kamaki(wizard['account'], wizard['token'], out)
kamaki = Kamaki(wizard['account'], out)
name = "%s-%s.diskdump" % (wizard['ImageName'],
time.strftime("%Y%m%d%H%M"))
......
......@@ -37,19 +37,14 @@ from kamaki.cli.config import Config
from kamaki.clients import ClientError
from kamaki.clients.image import ImageClient
from kamaki.clients.pithos import PithosClient
from kamaki.clients.astakos import AstakosClient
from image_creator.util import FatalError
CONTAINER = "images"
class Kamaki(object):
@staticmethod
def get_account():
config = Config()
return config.get('store', 'account') or \
config.get('global', 'account')
CONTAINER = "images"
@staticmethod
def get_token():
......@@ -57,31 +52,36 @@ class Kamaki(object):
return config.get('global', 'token')
@staticmethod
def save_account(account):
def save_token(token):
config = Config()
config.set('store', 'account', account)
config.set('global', 'token', token)
config.write()
@staticmethod
def save_token(token):
def get_account(token):
config = Config()
config.set('global', 'token', token)
config.write()
astakos = AstakosClient(config.get('astakos', 'url'), token)
try:
account = astakos.info()
except ClientError as e:
if e.status == 401: # Unauthorized: invalid token
return None
else:
raise
return account
def __init__(self, account, token, output):
def __init__(self, account, output):
self.account = account
self.token = token
self.out = output
config = Config()
pithos_url = config.get('store', 'url')
self.container = CONTAINER
self.pithos_client = PithosClient(pithos_url, self.token, self.account,
self.container)
self.pithos_client = PithosClient(pithos_url,
self.account['auth_token'], self.account['uuid'], self.CONTAINER)
image_url = config.get('image', 'url')
self.image_client = ImageClient(image_url, self.token)
self.image_client = ImageClient(image_url, self.account['auth_token'])
def upload(self, file_obj, size=None, remote_path=None, hp=None, up=None):
"""Upload a file to pithos"""
......@@ -89,7 +89,7 @@ class Kamaki(object):
path = basename(file_obj.name) if remote_path is None else remote_path
try:
self.pithos_client.create_container(self.container)
self.pithos_client.create_container(self.CONTAINER)
except ClientError as e:
if e.status != 202: # Ignore container already exists errors
raise e
......@@ -100,7 +100,8 @@ class Kamaki(object):
self.pithos_client.upload_object(path, file_obj, size, hash_cb,
upload_cb)
return "pithos://%s/%s/%s" % (self.account, self.container, path)
return "pithos://%s/%s/%s" % (self.account['uuid'], self.CONTAINER,
path)
def register(self, name, location, metadata):
"""Register an image to ~okeanos"""
......
......@@ -64,8 +64,6 @@ def parse_options(input_args):
usage = "Usage: %prog [options] <input_media>"
parser = optparse.OptionParser(version=version, usage=usage)
account = os.environ["OKEANOS_USER"] if "OKEANOS_USER" in os.environ \
else None
token = os.environ["OKEANOS_TOKEN"] if "OKEANOS_TOKEN" in os.environ \
else None
......@@ -92,16 +90,12 @@ def parse_options(input_args):
help="register the image with ~okeanos as IMAGENAME",
metavar="IMAGENAME")
parser.add_option("-a", "--account", dest="account", type="string",
default=account, help="use this ACCOUNT when "
"uploading/registering images [Default: %s]" % account)
parser.add_option("-m", "--metadata", dest="metadata", default=[],
help="add custom KEY=VALUE metadata to the image",
action="append", metavar="KEY=VALUE")
parser.add_option("-t", "--token", dest="token", type="string",
default=token, help="use this token when "
default=token, help="use this authentication token when "
"uploading/registering images [Default: %s]" % token)
parser.add_option("--print-sysprep", dest="print_sysprep", default=False,
......@@ -140,26 +134,21 @@ def parse_options(input_args):
if options.register and not options.upload:
raise FatalError("You also need to set -u when -r option is set")
if options.upload and options.account is None:
raise FatalError("Image uploading cannot be performed. No ~okeanos "
"account name is specified. Use -a to set an account "
"name.")
if options.upload and options.token is None:
raise FatalError("Image uploading cannot be performed. No ~okeanos "
"token is specified. User -t to set a token.")
raise FatalError("Image uploading cannot be performed. "
"No authentication token is specified. Use -t to set a token")
if options.tmp is not None and not os.path.isdir(options.tmp):
raise FatalError("The directory `%s' specified with --tmpdir is not "
"valid." % options.tmp)
"valid" % options.tmp)
meta = {}
for m in options.metadata:
try:
key, value = m.split('=', 1)
except ValueError:
raise FatalError("Metadata option: `%s' is not in "
"KEY=VALUE format." % m)
raise FatalError("Metadata option: `%s' is not in KEY=VALUE "
"format." % m)
meta[key] = value
options.metadata = meta
......@@ -193,7 +182,16 @@ def image_creator():
filename = "%s%s" % (options.outfile, extension)
if os.path.exists(filename):
raise FatalError("Output file %s exists "
"(use --force to overwrite it)." % filename)
"(use --force to overwrite it)" % filename)
# Check if the authentication token is valid. The earlier the better
try:
account = Kamaki.get_account(options.token)
if account is None:
raise FatalError("The authentication token you provided is not "
"valid!")
except ClientError as e:
raise FatalError("Astakos client: %d %s" % (e.status, e.message))
disk = Disk(options.source, out, options.tmp)
......@@ -270,13 +268,11 @@ def image_creator():
uploaded_obj = ""
if options.upload:
out.output("Uploading image to pithos:")
kamaki = Kamaki(options.account, options.token, out)
kamaki = Kamaki(account, out)
with open(snapshot, 'rb') as f:
uploaded_obj = kamaki.upload(f, size, options.upload,
"(1/4) Calculating block "
"hashes",
"(2/4) Uploading missing "
"blocks")
"(1/4) Calculating block hashes",
"(2/4) Uploading missing blocks")
out.output("(3/4) Uploading metadata file...", False)
kamaki.upload(StringIO.StringIO(metastring),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment