import binascii import logging import requests from pyotp import TOTP from uncloud.common.shared import shared from uncloud.common.settings import settings logger = logging.getLogger(__name__) def check_otp(name, realm, token): try: data = { 'auth_name': settings['otp']['auth_name'], 'auth_token': TOTP(settings['otp']['auth_seed']).now(), 'auth_realm': settings['otp']['auth_realm'], 'name': name, 'realm': realm, 'token': token, } except binascii.Error: logger.error('Cannot compute OTP for seed: {}'.format(settings['otp']['auth_seed'])) return 400 else: response = requests.post(settings['otp']['verification_controller_url'], json=data) return response.status_code def resolve_vm_name(name, owner): """Return UUID of Virtual Machine of name == name and owner == owner Input: name of vm, owner of vm. Output: uuid of vm if found otherwise None """ result = next( filter(lambda vm: vm.value['owner'] == owner and vm.value['name'] == name, shared.vm_pool.vms), None ) if result: return result.key.split('/')[-1] return None def resolve_image_name(name): """Return image uuid given its name and its store * If the provided name is not in correct format i.e {store_name}:{image_name} return ValueError * If no such image found then return KeyError """ seperator = ':' # Ensure, user/program passed valid name that is of type string try: store_name_and_image_name = name.split(seperator) """ Examples, where it would work and where it would raise exception 'images:alpine' --> ['images', 'alpine'] 'images' --> ['images'] it would raise Exception as non enough value to unpack 'images:alpine:meow' --> ['images', 'alpine', 'meow'] it would raise Exception as too many values to unpack """ store_name, image_name = store_name_and_image_name except Exception: raise ValueError('Image name not in correct format i.e {store_name}:{image_name}') images = shared.etcd_client.get_prefix(settings['etcd']['image_prefix'], value_in_json=True) # Try to find image with name == image_name and store_name == store_name try: image = next( filter( lambda im: im.value['name'] == image_name and im.value['store_name'] == store_name, images, ) ) except StopIteration: raise KeyError('No image with name {} found.'.format(name)) else: image_uuid = image.key.split('/')[-1] return image_uuid def make_return_message(err, status_code=200): return {'message': str(err)}, status_code