def get_new_token(credentials): username = lookup(credentials, 'auth', 'passwordCredentials', 'username') credential = lookup(credentials, 'auth', 'passwordCredentials', 'password') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = Client(username=username, api_key=credential) user = client['Account'].getCurrentUser(mask=USER_MASK) return {'username': username, 'api_key': credential, 'auth_type': 'api_key', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user else: client = Client() client.auth = None try: userId, tokenHash = client.authenticate_with_password(username, credential) user = client['Account'].getCurrentUser(mask=USER_MASK) return {'userId': userId, 'tokenHash': tokenHash, 'auth_type': 'token', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user except SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_User_Customer_LoginFailed': raise Unauthorized(e.faultString) raise
def authenticate(self, creds): username = utils.lookup(creds,'auth','passwordCredentials','username') credential = utils.lookup(creds,'auth','passwordCredentials','password') token_id = utils.lookup(creds, 'auth', 'token', 'id') token_driver = identity.token_driver() token_auth = None # If token_id exists, get UID/Password associated w/ this token. if token_id: token = identity.token_id_driver().token_from_id(token_id) token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) token_auth = token['auth_type'] == 'token' headers = {"Accept": "application/json", "Content-Type": "application/json"} auth = (username, credential) resp = requests.get("https://cloud.skytap.com/users", headers=headers, auth=auth) if resp.status_code == 200: payload = json.loads(resp.text) user_id = utils.lookup(payload[0], 'id') auth_type = "token" if token_auth else "api_key" sys.stderr.write("auth_type: %s" % auth_type) return {'user': {"id": user_id, "username": username, "accountId": user_id}, 'credential': credential, 'auth_type': auth_type} return None
def test_lookup(self): self.assertIsNone(lookup({}, 'key')) self.assertEqual(lookup({'key': 'value'}, 'key'), 'value') self.assertEqual(lookup({'key': { 'key': 'value' }}, 'key', 'key'), 'value')
def authenticate(self, creds): username = lookup(creds, 'auth', 'passwordCredentials', 'username') credential = lookup(creds, 'auth', 'passwordCredentials', 'password') token_id = lookup(creds, 'auth', 'token', 'id') token_auth = None if token_id: token = identity.token_id_driver().token_from_id(token_id) token_driver = identity.token_driver() token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) token_auth = token['auth_type'] == 'token' def assert_tenant(user): tenant = lookup(creds, 'auth', 'tenantId') or lookup(creds, 'auth', 'tenantName') if tenant and str(user['accountId']) != tenant: raise Unauthorized('Invalid username, password or tenant id') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = Client(username=username, api_key=credential, endpoint_url=cfg.CONF['softlayer']['endpoint'], proxy=cfg.CONF['softlayer']['proxy']) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return {'user': user, 'credential': credential, 'auth_type': 'api_key'} else: client = Client(endpoint_url=cfg.CONF['softlayer']['endpoint'], proxy=cfg.CONF['softlayer']['proxy']) client.auth = None try: if token_auth: client.auth = TokenAuthentication(token['user_id'], credential) else: userId, tokenHash = client.\ authenticate_with_password(username, credential) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) if token_auth: tokenHash = credential return {'user': user, 'credential': tokenHash, 'auth_type': 'token'} except SoftLayerAPIError as e: if (e.faultCode == "SoftLayer_Exception_User_Customer" "_LoginFailed"): raise Unauthorized(e.faultString) raise
def authenticate(self, creds): username = lookup(creds, 'auth', 'passwordCredentials', 'username') credential = lookup(creds, 'auth', 'passwordCredentials', 'password') token_id = lookup(creds, 'auth', 'token', 'id') if token_id: token = identity.token_id_driver().token_from_id(token_id) token_driver = identity.token_driver() token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) def assert_tenant(user): tenant = lookup(creds, 'auth', 'tenantId') or lookup( creds, 'auth', 'tenantName') if tenant and str(user['accountId']) != tenant: raise Unauthorized('Invalid username, password or tenant id') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = Client(username=username, api_key=credential, endpoint_url=cfg.CONF['softlayer']['endpoint'], proxy=cfg.CONF['softlayer']['proxy']) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return { 'user': user, 'credential': credential, 'auth_type': 'api_key' } else: client = Client(endpoint_url=cfg.CONF['softlayer']['endpoint'], proxy=cfg.CONF['softlayer']['proxy']) client.auth = None try: userId, tokenHash = client.\ authenticate_with_password(username, credential) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return { 'user': user, 'credential': tokenHash, 'auth_type': 'token' } except SoftLayerAPIError as e: if (e.faultCode == "SoftLayer_Exception_User_Customer" "_LoginFailed"): raise Unauthorized(e.faultString) raise
def _get_user_id_from_metadata(instance): uid = utils.lookup(instance, 'billingItem', 'orderItem', 'order', 'userRecordId') if not uid: # Attempt to lookup a stashed user_id in the metadata userdata = utils.lookup(instance, 'userData') # userData is a list with a single dict with a single 'value' key # like: userData = [{'value': userdata}] if userdata: # FIXME(mriedem): This needs to be base64 decoded. userdata = json.loads(userdata[0]['value']) uid = userdata.get('metadata', {}).get(METADATA_USERID) if not uid: uid = '' return str(uid)
def on_put(self, req, resp, tenant_id, server_id): client = req.env["sl_client"] cci = CCIManager(client) body = json.loads(req.stream.read().decode()) if "name" in lookup(body, "server"): if lookup(body, "server", "name").strip() == "": return bad_request(resp, message="Server name is blank") cci.edit(server_id, hostname=lookup(body, "server", "name")) instance = cci.get_instance(server_id, mask=get_virtual_guest_mask()) results = get_server_details_dict(self.app, req, instance) resp.body = {"server": results}
def on_put(self, req, resp, tenant_id, server_id): client = req.env['sl_client'] cci = CCIManager(client) body = json.loads(req.stream.read().decode()) if 'name' in lookup(body, 'server'): if lookup(body, 'server', 'name').strip() == '': return bad_request(resp, message='Server name is blank') cci.edit(server_id, hostname=lookup(body, 'server', 'name')) instance = cci.get_instance(server_id, mask=get_virtual_guest_mask()) results = get_server_details_dict(self.app, req, instance) resp.body = {'server': results}
def on_get(self, req, resp, tenant_id=None): client = req.env['sl_client'] tenant_id = tenant_id or utils.lookup(req.env, 'auth', 'tenant_id') images = [] for image in get_all_images(client): img = get_v2_image_details_dict(self.app, req, image, tenant_id) # Apply conditions from filters # TODO(zhiyan): Will add more filters continuously # with requirement-driven way. if req.get_param('name'): if img['name'] != req.get_param('name'): continue images.append(img) sorted_images = sorted(images, key=lambda x: x['id'].lower()) if req.get_param('marker'): predicate = lambda x: x['id'] <= req.get_param('marker') sorted_images = list(itertools.dropwhile(predicate, sorted_images)) if req.get_param('limit'): sorted_images = sorted_images[:int(req.get_param('limit'))] resp.status = 200 resp.body = {'images': sorted_images}
def on_get(self, req, resp, tenant_id=None): client = req.env['sl_client'] tenant_id = tenant_id or lookup(req.env, 'auth', 'tenant_id') image_obj = SLImages(client) output = [] limit = None if req.get_param('limit'): limit = int(req.get_param('limit')) for visibility, funct in [('public', image_obj.get_public_images), ('private', image_obj.get_private_images)]: if limit == 0: break results = funct(name=req.get_param('name'), limit=limit) if not results: continue if not isinstance(results, list): results = [results] for image in results: formatted_image = get_v2_image_details_dict( self.app, req, image, tenant_id) if formatted_image: formatted_image['visibility'] = visibility output.append(formatted_image) if limit is not None: limit -= 1 resp.body = {'images': sorted(output, key=lambda x: x['name'].lower())}
def on_put(self, req, resp, tenant_id, server_id): client = req.sl_client vs = SoftLayer.VSManager(client) body = json.loads(req.stream.read().decode()) if 'name' in utils.lookup(body, 'server'): if utils.lookup(body, 'server', 'name').strip() == '': return error_handling.bad_request( resp, message='Server name is blank') vs.edit(server_id, hostname=utils.lookup(body, 'server', 'name')) instance = vs.get_instance(server_id, mask=get_virtual_guest_mask()) results = get_server_details_dict(self.app, req, instance, False) resp.body = {'server': results}
def on_get(self, req, resp, tenant_id=None): client = req.sl_client tenant_id = tenant_id or utils.lookup(req.env, 'auth', 'tenant_id') images = [] for image in get_all_images(client): img = get_v2_image_details_dict(self.app, req, image, tenant_id, self.detail) # Apply conditions from filters # TODO(zhiyan): Will add more filters continuously # with requirement-driven way. if req.get_param('name'): if img['name'] != req.get_param('name'): continue images.append(img) sorted_images = sorted(images, key=lambda x: x['id'].lower()) if req.get_param('marker'): predicate = lambda x: x['id'] <= req.get_param('marker') sorted_images = list(itertools.dropwhile(predicate, sorted_images)) if req.get_param('limit'): sorted_images = sorted_images[:int(req.get_param('limit'))] resp.status = 200 resp.body = {'images': sorted_images}
def on_put(self, req, resp, tenant_id, domain, entry): client = req.env['sl_client'] mgr = DNSManager(client) body = json.loads(req.stream.read().decode()) ip = lookup(body, 'dns_entry', 'ip') record_type = lookup(body, 'dns_entry', 'type') if not record_type: record_type = 'A' domain = unquote_plus(domain) zone_id = mgr._get_zone_id_from_name(domain)[0] mgr.create_record(zone_id=zone_id, record=entry, record_type=record_type, data=ip) new_record = mgr.get_records(zone_id, host=entry)[0] result = get_dns_entry_dict(domain, entry, ip, record_type, entry_id=new_record['id']) resp.body = {'dns_entry': result}
def get_new_token(credentials): username = utils.lookup(credentials, 'auth', 'passwordCredentials', 'username') credential = utils.lookup(credentials, 'auth', 'passwordCredentials', 'password') def assert_tenant(user): tenant = utils.lookup(credentials, 'auth', 'tenantId') if tenant and str(user['accountId']) != tenant: raise exceptions.Unauthorized( 'Invalid username, password or tenant id') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = SoftLayer.Client(username=username, api_key=credential) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return {'username': username, 'api_key': credential, 'auth_type': 'api_key', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user else: client = SoftLayer.Client() client.auth = None try: userId, tokenHash = client.authenticate_with_password(username, credential) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return {'userId': userId, 'tokenHash': tokenHash, 'auth_type': 'token', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user except SoftLayer.SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_User_Customer_LoginFailed': raise exceptions.Unauthorized(e.faultString) raise
def on_post(self, req, resp, tenant_id): payload = {} client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) payload['hostname'] = body['server']['name'] payload['domain'] = config.CONF['default_domain'] or 'jumpgate.com' payload['image_id'] = body['server']['imageRef'] # TODO(kmcdonald) - How do we set this accurately? payload['hourly'] = True networks = utils.lookup(body, 'server', 'networks') cci = SoftLayer.CCIManager(client) try: self._handle_flavor(payload, body) self._handle_sshkeys(payload, body, client) self._handle_user_data(payload, body) self._handle_datacenter(payload, body) if networks: self._handle_network(payload, client, networks) new_instance = cci.create_instance(**payload) except Exception as e: return error_handling.bad_request(resp, message=str(e)) # This should be the first tag that the VS set. Adding any more tags # will replace this tag try: flavor_id = int(body['server'].get('flavorRef')) vs = client['Virtual_Guest'] vs.setTags('{"flavor_id": ' + str(flavor_id) + '}', id=new_instance['id']) except Exception: pass resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = { 'server': { 'id': new_instance['id'], 'links': [{ 'href': self.app.get_endpoint_url('compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self' }], 'adminPass': '', } }
def authenticate(self, creds): username = lookup(creds, "auth", "passwordCredentials", "username") credential = lookup(creds, "auth", "passwordCredentials", "password") token_id = lookup(creds, "auth", "token", "id") if token_id: token = identity.token_id_driver().token_from_id(token_id) token_driver = identity.token_driver() token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) def assert_tenant(user): tenant = lookup(creds, "auth", "tenantId") or lookup(creds, "auth", "tenantName") if tenant and str(user["accountId"]) != tenant: raise Unauthorized("Invalid username, password or tenant id") # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = Client( username=username, api_key=credential, endpoint_url=cfg.CONF["softlayer"]["endpoint"], proxy=cfg.CONF["softlayer"]["proxy"], ) user = client["Account"].getCurrentUser(mask=USER_MASK) assert_tenant(user) return {"user": user, "credential": credential, "auth_type": "api_key"} else: client = Client(endpoint_url=cfg.CONF["softlayer"]["endpoint"], proxy=cfg.CONF["softlayer"]["proxy"]) client.auth = None try: userId, tokenHash = client.authenticate_with_password(username, credential) user = client["Account"].getCurrentUser(mask=USER_MASK) assert_tenant(user) return {"user": user, "credential": tokenHash, "auth_type": "token"} except SoftLayerAPIError as e: if e.faultCode == "SoftLayer_Exception_User_Customer" "_LoginFailed": raise Unauthorized(e.faultString) raise
def on_post(self, req, resp, tenant_id): payload = {} client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) payload['hostname'] = body['server']['name'] payload['domain'] = config.CONF['default_domain'] or 'jumpgate.com' payload['image_id'] = body['server']['imageRef'] # TODO(kmcdonald) - How do we set this accurately? payload['hourly'] = True networks = utils.lookup(body, 'server', 'networks') cci = SoftLayer.CCIManager(client) try: self._handle_flavor(payload, body) self._handle_sshkeys(payload, body, client) self._handle_user_data(payload, body) self._handle_datacenter(payload, body) if networks: self._handle_network(payload, client, networks) new_instance = cci.create_instance(**payload) except Exception as e: return error_handling.bad_request(resp, message=str(e)) # This should be the first tag that the VS set. Adding any more tags # will replace this tag try: flavor_id = int(body['server'].get('flavorRef')) vs = client['Virtual_Guest'] vs.setTags('{"flavor_id": ' + str(flavor_id) + '}', id=new_instance['id']) except Exception: pass resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = {'server': { # Casted to string to make tempest pass 'id': str(new_instance['id']), 'links': [{ 'href': self.app.get_endpoint_url( 'compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self'}], 'adminPass': '', # TODO(imkarrer) - Added security_groups to make tempest pass, need real groups # noqa 'security_groups': [] }}
def on_put(self, req, resp, tenant_id, domain, entry): client = req.env['sl_client'] mgr = SoftLayer.DNSManager(client) body = json.loads(req.stream.read().decode()) ip = utils.lookup(body, 'dns_entry', 'ip') record_type = utils.lookup(body, 'dns_entry', 'type') if not record_type: record_type = 'A' domain = parse.unquote_plus(domain) zone_id = mgr._get_zone_id_from_name(domain)[0] mgr.create_record(zone_id=zone_id, record=entry, record_type=record_type, data=ip) new_record = mgr.get_records(zone_id, host=entry)[0] result = get_dns_entry_dict(domain, entry, ip, record_type, entry_id=new_record['id']) resp.body = {'dns_entry': result}
def _handle_user_data(self, payload, body): user_data = {} if utils.lookup(body, 'server', 'metadata'): user_data['metadata'] = utils.lookup(body, 'server', 'metadata') if utils.lookup(body, 'server', 'user_data'): user_data['user_data'] = utils.lookup(body, 'server', 'user_data') if utils.lookup(body, 'server', 'personality'): user_data['personality'] = utils.lookup(body, 'server', 'personality') payload['userdata'] = json.dumps(user_data)
def on_get(self, req, resp, tenant_id): client = req.env['sl_client'] cci = CCIManager(client) all_options = cci.get_create_options() results = [] # Load and sort all data centers for option in all_options['datacenters']: name = lookup(option, 'template', 'datacenter', 'name') results.append({'zoneState': {'available': True}, 'hosts': None, 'zoneName': name}) results = sorted(results, key=lambda x: x['zoneName']) resp.body = {'availabilityZoneInfo': results}
def _handle_user_data(self, payload, body): user_data = {} if utils.lookup(body, 'server', 'metadata'): user_data['metadata'] = utils.lookup(body, 'server', 'metadata') if utils.lookup(body, 'server', 'user_data'): user_data['user_data'] = utils.lookup(body, 'server', 'user_data') if utils.lookup(body, 'server', 'personality'): user_data['personality'] = utils.lookup(body, 'server', 'personality') # FIXME(mriedem): This needs to be base64 encoded payload['userdata'] = json.dumps(user_data)
def on_get(self, req, resp, tenant_id=None): client = req.env['sl_client'] tenant_id = tenant_id or utils.lookup(req.env, 'auth', 'tenant_id') image_obj = SLImages(client) output = [] limit = None if req.get_param('limit'): limit = int(req.get_param('limit')) marker = req.get_param('marker') for visibility, funct in [('public', image_obj.get_public_images), ('private', image_obj.get_private_images)]: if limit == 0: break results = funct(name=req.get_param('name'), limit=limit, marker=marker) if not results: continue if not isinstance(results, list): results = [results] for image in results: formatted_image = get_v2_image_details_dict(self.app, req, image, tenant_id) if formatted_image: formatted_image['visibility'] = visibility output.append(formatted_image) if limit is not None: limit -= 1 resp.body = {'images': sorted(output, key=lambda x: x['name'].lower())}
def on_get(self, req, resp, tenant_id): client = req.env['sl_client'] cci = CCIManager(client) all_options = cci.get_create_options() results = [] # Load and sort all data centers for option in all_options['datacenters']: name = lookup(option, 'template', 'datacenter', 'name') results.append({ 'zoneState': { 'available': True }, 'hosts': None, 'zoneName': name }) results = sorted(results, key=lambda x: x['zoneName']) resp.body = {'availabilityZoneInfo': results}
def get_server_details_dict(app, req, instance): image_id = utils.lookup(instance, 'blockDeviceTemplateGroup', 'globalIdentifier') tenant_id = instance['accountId'] # TODO(kmcdonald) - Don't hardcode this flavor ID flavor_url = app.get_endpoint_url( 'compute', req, 'v2_flavor', flavor_id=1) server_url = app.get_endpoint_url( 'compute', req, 'v2_server', server_id=instance['id']) task_state = None transaction = utils.lookup(instance, 'activeTransaction', 'transactionStatus', 'name') if transaction and any(['RECLAIM' in transaction, 'TEAR_DOWN' in transaction]): task_state = 'deleting' else: task_state = transaction # Map SL Power States to OpenStack Power States power_state = 0 status = 'UNKNOWN' sl_power_state = instance['powerState']['keyName'] if sl_power_state == 'RUNNING': if transaction or not instance.get('provisionDate'): status = 'BUILD' power_state = OPENSTACK_POWER_MAP['BLOCKED'] else: status = 'ACTIVE' power_state = OPENSTACK_POWER_MAP['RUNNING'] elif sl_power_state == 'PAUSED': status = 'PAUSED' power_state = OPENSTACK_POWER_MAP['PAUSED'] elif sl_power_state in OPENSTACK_POWER_MAP: power_state = OPENSTACK_POWER_MAP[sl_power_state] elif sl_power_state == 'HALTED' and instance.get('provisionDate'): status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['SHUTOFF'] elif sl_power_state == 'HALTED': status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['BLOCKED'] addresses = {} if instance.get('primaryBackendIpAddress'): addresses['private'] = [{ 'addr': instance.get('primaryBackendIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] if instance.get('primaryIpAddress'): addresses['public'] = [{ 'addr': instance.get('primaryIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] # TODO(kmcdonald) - Don't hardcode this image_name = '' results = { 'id': str(instance['id']), 'accessIPv4': '', 'accessIPv6': '', 'addresses': addresses, 'created': instance['createDate'], # TODO(nbeitenmiller) - Do I need to run this through isoformat()? 'flavor': { # TODO(kmcdonald) - Make this realistic 'id': '1', 'links': [ { 'href': flavor_url, 'rel': 'bookmark', }, ], }, 'hostId': instance['id'], 'links': [ { 'href': server_url, 'rel': 'self', } ], 'name': instance['hostname'], 'OS-EXT-AZ:availability_zone': utils.lookup(instance, 'datacenter', 'id'), 'OS-EXT-STS:power_state': power_state, 'OS-EXT-STS:task_state': task_state, 'OS-EXT-STS:vm_state': instance['status']['keyName'], 'security_groups': [{'name': 'default'}], 'status': status, 'tenant_id': tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key. Otherwise it will be None 'user_id': utils.lookup(instance, 'billingItem', 'orderItem', 'order', 'userRecordId'), 'updated': instance['modifyDate'], 'image_name': image_name, } # OpenStack only supports having one SSH Key assigned to an instance if instance['sshKeys']: results['key_name'] = instance['sshKeys'][0]['label'] if image_id: results['image'] = { 'id': image_id, 'links': [ { 'href': app.get_endpoint_url( 'compute', req, 'v2_image', image_id=image_id), 'rel': 'self', }, ], } return results
def on_post(self, req, resp, tenant_id): client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) flavor_id = int(body['server'].get('flavorRef')) if flavor_id not in flavors.FLAVORS: return error_handling.bad_request(resp, 'Flavor could not be found') flavor = flavors.FLAVORS[flavor_id] ssh_keys = [] key_name = body['server'].get('key_name') if key_name: sshkey_mgr = SoftLayer.SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return error_handling.bad_request(resp, 'KeyPair could not be found') ssh_keys.append(keys[0]['id']) private_network_only = False networks = utils.lookup(body, 'server', 'networks') if networks: # Make sure they're valid networks if not all([network['uuid'] in ['public', 'private'] in network for network in networks]): return error_handling.bad_request(resp, message='Invalid network') # Find out if it's private only if not any([network['uuid'] == 'public' in network for network in networks]): private_network_only = True user_data = {} if utils.lookup(body, 'server', 'metadata'): user_data['metadata'] = utils.lookup(body, 'server', 'metadata') if utils.lookup(body, 'server', 'user_data'): user_data['user_data'] = utils.lookup(body, 'server', 'user_data') if utils.lookup(body, 'server', 'personality'): user_data['personality'] = utils.lookup(body, 'server', 'personality') datacenter = (utils.lookup(body, 'server', 'availability_zone') or config.CONF['compute']['default_availability_zone']) if not datacenter: return error_handling.bad_request(resp, 'availability_zone missing') cci = SoftLayer.CCIManager(client) payload = { 'hostname': body['server']['name'], 'domain': config.CONF['default_domain'] or 'jumpgate.com', 'cpus': flavor['cpus'], 'memory': flavor['ram'], 'local_disk': False if flavor['disk-type'] == 'SAN' else True, 'hourly': True, # TODO(kmcdonald) - How do we set this accurately? 'datacenter': datacenter, 'image_id': body['server']['imageRef'], 'ssh_keys': ssh_keys, 'private': private_network_only, 'userdata': json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return error_handling.bad_request(resp, message=str(e)) resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = {'server': { 'id': new_instance['id'], 'links': [{ 'href': self.app.get_endpoint_url( 'compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self'}], 'adminPass': '', }}
def on_post(self, req, resp, tenant_id): client = req.env["sl_client"] body = json.loads(req.stream.read().decode()) flavor_id = int(body["server"].get("flavorRef")) if flavor_id not in FLAVORS: return bad_request(resp, "Flavor could not be found") flavor = FLAVORS[flavor_id] ssh_keys = [] key_name = body["server"].get("key_name") if key_name: sshkey_mgr = SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return bad_request(resp, "KeyPair could not be found") ssh_keys.append(keys[0]["id"]) private_network_only = False networks = lookup(body, "server", "networks") if networks: # Make sure they're valid networks if not all([network["uuid"] in ["public", "private"] in network for network in networks]): return bad_request(resp, message="Invalid network") # Find out if it's private only if not any([network["uuid"] == "public" in network for network in networks]): private_network_only = True user_data = {} if lookup(body, "server", "metadata"): user_data["metadata"] = lookup(body, "server", "metadata") if lookup(body, "server", "user_data"): user_data["user_data"] = lookup(body, "server", "user_data") if lookup(body, "server", "personality"): user_data["personality"] = lookup(body, "server", "personality") datacenter = None if lookup(body, "server", "availability_zone"): datacenter = lookup(body, "server", "availability_zone") cci = CCIManager(client) payload = { "hostname": body["server"]["name"], "domain": CONF["default_domain"] or "jumpgate.com", "cpus": flavor["cpus"], "memory": flavor["ram"], "local_disk": False if flavor["disk-type"] == "SAN" else True, "hourly": True, # TODO - How do we set this accurately? "datacenter": datacenter, "image_id": body["server"]["imageRef"], "ssh_keys": ssh_keys, "private": private_network_only, "userdata": json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return bad_request(resp, message=str(e)) resp.set_header("x-compute-request-id", "create") resp.status = 202 resp.body = { "server": { "id": new_instance["id"], "links": [ { "href": self.app.get_endpoint_url("compute", req, "v2_server", instance_id=new_instance["id"]), "rel": "self", } ], "adminPass": "", } }
def get_server_details_dict(app, req, instance, is_list): image_id = utils.lookup(instance, 'blockDeviceTemplateGroup', 'globalIdentifier') tenant_id = instance['accountId'] client = req.env['sl_client'] vs = client['Virtual_Guest'] flavor_url = None flavor_id = 1 if is_list: tags = vs.getTagReferences(id=instance['id']) for tag in tags: if 'flavor_id' in tag['tag']['name']: try: # Try to parse the flavor id from the tag format # i.e. 'flavor_id: 2' tag_string = tag['tag']['name'] flavor_id = int(re.search(r'\d+', tag_string).group()) flavor_url = app.get_endpoint_url( 'compute', req, 'v2_flavor', flavor_id=flavor_id) except Exception: pass # Workaround of hardcoded ID for VS's created before flavor-id # pushed into tags if not flavor_url: flavor_url = app.get_endpoint_url( 'compute', req, 'v2_flavor', flavor_id=1) server_url = app.get_endpoint_url( 'compute', req, 'v2_server', server_id=instance['id']) task_state = None transaction = utils.lookup(instance, 'activeTransaction', 'transactionStatus', 'name') if transaction and any(['RECLAIM' in transaction, 'TEAR_DOWN' in transaction]): task_state = 'deleting' else: task_state = transaction # Map SL Power States to OpenStack Power States power_state = 0 status = 'UNKNOWN' sl_power_state = instance['powerState']['keyName'] if sl_power_state == 'RUNNING': if transaction or not instance.get('provisionDate'): status = 'BUILD' power_state = OPENSTACK_POWER_MAP['BLOCKED'] else: status = 'ACTIVE' power_state = OPENSTACK_POWER_MAP['RUNNING'] elif sl_power_state == 'PAUSED': status = 'PAUSED' power_state = OPENSTACK_POWER_MAP['PAUSED'] elif sl_power_state in OPENSTACK_POWER_MAP: power_state = OPENSTACK_POWER_MAP[sl_power_state] elif sl_power_state == 'HALTED' and instance.get('provisionDate'): status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['SHUTOFF'] elif sl_power_state == 'HALTED': status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['BLOCKED'] addresses = {} if instance.get('primaryBackendIpAddress'): addresses['private'] = [{ 'addr': instance.get('primaryBackendIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] if instance.get('primaryIpAddress'): addresses['public'] = [{ 'addr': instance.get('primaryIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] # TODO(kmcdonald) - Don't hardcode this image_name = '' results = { 'id': str(instance['id']), 'accessIPv4': '', 'accessIPv6': '', 'addresses': addresses, 'created': instance['createDate'], # TODO(nbeitenmiller) - Do I need to run this through isoformat()? 'flavor': { 'id': str(flavor_id), 'links': [ { 'href': flavor_url, 'rel': 'bookmark', }, ], }, 'hostId': instance['id'], 'links': [ { 'href': server_url, 'rel': 'self', } ], 'name': instance['hostname'], 'OS-EXT-AZ:availability_zone': utils.lookup(instance, 'datacenter', 'id'), 'OS-EXT-STS:power_state': power_state, 'OS-EXT-STS:task_state': task_state, 'OS-EXT-STS:vm_state': instance['status']['keyName'], 'security_groups': [{'name': 'default'}], 'status': status, 'tenant_id': tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key. Otherwise it will be None 'user_id': utils.lookup(instance, 'billingItem', 'orderItem', 'order', 'userRecordId'), 'updated': instance['modifyDate'], 'image_name': image_name, } # OpenStack only supports having one SSH Key assigned to an instance if instance['sshKeys']: results['key_name'] = instance['sshKeys'][0]['label'] if image_id: results['image'] = { 'id': image_id, 'links': [ { 'href': app.get_endpoint_url( 'compute', req, 'v2_image', image_id=image_id), 'rel': 'self', }, ], } return results
def get_server_details_dict(app, req, instance): image_id = lookup(instance, 'blockDeviceTemplateGroup', 'globalIdentifier') tenant_id = instance['accountId'] # TODO - Don't hardcode this flavor ID flavor_url = app.get_endpoint_url('compute', req, 'v2_flavor', flavor_id=1) server_url = app.get_endpoint_url('compute', req, 'v2_server', server_id=instance['id']) task_state = None transaction = lookup(instance, 'activeTransaction', 'transactionStatus', 'name') if transaction and 'RECLAIM' in transaction: task_state = 'deleting' else: task_state = transaction # Map SL Power States to OpenStack Power States power_state = 0 status = 'UNKNOWN' sl_power_state = instance['powerState']['keyName'] if sl_power_state == 'RUNNING': if transaction or not instance.get('provisionDate'): status = 'BUILD' power_state = OPENSTACK_POWER_MAP['BLOCKED'] else: status = 'ACTIVE' power_state = OPENSTACK_POWER_MAP['RUNNING'] elif sl_power_state == 'PAUSED': status = 'PAUSED' power_state = OPENSTACK_POWER_MAP['PAUSED'] elif sl_power_state in OPENSTACK_POWER_MAP: power_state = OPENSTACK_POWER_MAP[sl_power_state] elif sl_power_state == 'HALTED' and instance.get('provisionDate'): status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['SHUTOFF'] elif sl_power_state == 'HALTED': status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['BLOCKED'] addresses = {} if instance.get('primaryBackendIpAddress'): addresses['private'] = [{ 'addr': instance.get('primaryBackendIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] if instance.get('primaryIpAddress'): addresses['public'] = [{ 'addr': instance.get('primaryIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] # TODO - Don't hardcode this image_name = '' results = { 'id': str(instance['id']), 'accessIPv4': '', 'accessIPv6': '', 'addresses': addresses, 'created': instance['createDate'], # TODO - Do I need to run this through isoformat()? 'flavor': { # TODO - Make this realistic 'id': '1', 'links': [ { 'href': flavor_url, 'rel': 'bookmark', }, ], }, 'hostId': instance['id'], 'links': [{ 'href': server_url, 'rel': 'self', }], 'name': instance['hostname'], 'OS-EXT-AZ:availability_zone': lookup(instance, 'datacenter', 'id'), 'OS-EXT-STS:power_state': power_state, 'OS-EXT-STS:task_state': task_state, 'OS-EXT-STS:vm_state': instance['status']['keyName'], 'security_groups': [{ 'name': 'default' }], 'status': status, 'tenant_id': tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key. Otherwise it will be None 'user_id': lookup(instance, 'billingItem', 'orderItem', 'order', 'userRecordId'), 'updated': instance['modifyDate'], 'image_name': image_name, } # OpenStack only supports having one SSH Key assigned to an instance if instance['sshKeys']: results['key_name'] = instance['sshKeys'][0]['label'] if image_id: results['image'] = { 'id': image_id, 'links': [ { 'href': app.get_endpoint_url('compute', req, 'v2_image', image_id=image_id), 'rel': 'self', }, ], } return results
def _handle_datacenter(self, payload, body): datacenter = (utils.lookup(body, 'server', 'availability_zone') or config.CONF['compute']['default_availability_zone']) if not datacenter: raise Exception('availability_zone missing') payload['datacenter'] = datacenter
def on_post(self, req, resp, tenant_id): client = req.env['sl_client'] body = json.loads(req.stream.read().decode()) flavor_id = int(body['server'].get('flavorRef')) if flavor_id not in FLAVORS: return bad_request(resp, 'Flavor could not be found') flavor = FLAVORS[flavor_id] ssh_keys = [] key_name = body['server'].get('key_name') if key_name: sshkey_mgr = SshKeyManager(client) keys = sshkey_mgr.list_keys(label=key_name) if len(keys) == 0: return bad_request(resp, 'KeyPair could not be found') ssh_keys.append(keys[0]['id']) private_network_only = False networks = lookup(body, 'server', 'networks') if networks: # Make sure they're valid networks if not all([ network['uuid'] in ['public', 'private'] in network for network in networks ]): return bad_request(resp, message='Invalid network') # Find out if it's private only if not any([ network['uuid'] == 'public' in network for network in networks ]): private_network_only = True user_data = {} if lookup(body, 'server', 'metadata'): user_data['metadata'] = lookup(body, 'server', 'metadata') if lookup(body, 'server', 'user_data'): user_data['user_data'] = lookup(body, 'server', 'user_data') if lookup(body, 'server', 'personality'): user_data['personality'] = lookup(body, 'server', 'personality') datacenter = None if lookup(body, 'server', 'availability_zone'): datacenter = lookup(body, 'server', 'availability_zone') cci = CCIManager(client) payload = { 'hostname': body['server']['name'], 'domain': 'jumpgate.com', # TODO - Don't hardcode this 'cpus': flavor['cpus'], 'memory': flavor['ram'], 'hourly': True, # TODO - How do we set this accurately? 'datacenter': datacenter, 'image_id': body['server']['imageRef'], 'ssh_keys': ssh_keys, 'private': private_network_only, 'userdata': json.dumps(user_data), } try: new_instance = cci.create_instance(**payload) except ValueError as e: return bad_request(resp, message=str(e)) resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = { 'server': { 'id': new_instance['id'], 'links': [{ 'href': self.app.get_endpoint_url('compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self' }], 'adminPass': '', } }
def authenticate(self, creds): username = utils.lookup(creds, 'auth', 'passwordCredentials', 'username') credential = utils.lookup(creds, 'auth', 'passwordCredentials', 'password') token_id = utils.lookup(creds, 'auth', 'token', 'id') token_driver = identity.token_driver() token_auth = None if token_id: token = identity.token_id_driver().token_from_id(token_id) token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) token_auth = token['auth_type'] == 'token' def assert_tenant(user): tenant = (utils.lookup(creds, 'auth', 'tenantId') or utils.lookup(creds, 'auth', 'tenantName')) if tenant and str(user['accountId']) != tenant: raise exceptions.Unauthorized( 'Invalid username, password or tenant id') endpoint = config.PARSER.get('softlayer', 'endpoint') proxy = config.PARSER.get('softlayer', 'proxy') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: client = SoftLayer.Client(username=username, api_key=credential, endpoint_url=endpoint, proxy=proxy) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) return { 'user': user, 'credential': credential, 'auth_type': 'api_key' } else: client = SoftLayer.Client(endpoint_url=endpoint, proxy=proxy) client.auth = None try: if token_auth: client.auth = SoftLayer.TokenAuthentication( token['user_id'], credential) else: userId, tokenHash = (client.authenticate_with_password( username, credential)) user = client['Account'].getCurrentUser(mask=USER_MASK) assert_tenant(user) if token_auth: tokenHash = credential return { 'user': user, 'credential': tokenHash, 'auth_type': 'token' } except SoftLayer.SoftLayerAPIError as e: if (e.faultCode == "SoftLayer_Exception_User_Customer" "_LoginFailed"): raise exceptions.Unauthorized(e.faultString) raise
def test_lookup(self): self.assertEquals(lookup({}, 'key'), None) self.assertEquals(lookup({'key': 'value'}, 'key'), 'value') self.assertEquals( lookup({'key': {'key': 'value'}}, 'key', 'key'), 'value')
def assert_tenant(user): tenant = lookup(creds, 'auth', 'tenantId') or lookup(creds, 'auth', 'tenantName') if tenant and str(user['accountId']) != tenant: raise Unauthorized('Invalid username, password or tenant id')
def assert_tenant(user): tenant = lookup(creds, "auth", "tenantId") or lookup(creds, "auth", "tenantName") if tenant and str(user["accountId"]) != tenant: raise Unauthorized("Invalid username, password or tenant id")
def on_post(self, req, resp, tenant_id): payload = {} client = req.sl_client body = json.loads(req.stream.read().decode()) payload['hostname'] = body['server']['name'] payload['domain'] = config.CONF['default_domain'] or 'jumpgate.com' payload['image_id'] = body['server']['imageRef'] # TODO(kmcdonald) - How do we set this accurately? payload['hourly'] = True networks = utils.lookup(body, 'server', 'networks') vs = SoftLayer.VSManager(client) try: self._handle_flavor(payload, body) self._handle_sshkeys(payload, body, client) # NOTE(mriedem): This is a hack but we need to stash the user_id # in the metadata on the virtual guest since the user's account # might not let them lookup billing information later during GET. self._stash_user_id_in_metadata(req, body) self._handle_user_data(payload, body) self._handle_datacenter(payload, body) if networks: self._handle_network(payload, client, networks) new_instance = vs.create_instance(**payload) except Exception as e: return error_handling.bad_request(resp, message=str(e)) # This should be the first tag that the VS set. Adding any more tags # will replace this tag try: flavor_id = int(body['server'].get('flavorRef')) vs = client['Virtual_Guest'] vs.setTags('{"flavor_id": ' + str(flavor_id) + '}', id=new_instance['id']) except Exception: pass resp.set_header('x-compute-request-id', 'create') resp.status = 202 resp.body = { 'server': { # Casted to string to make tempest pass 'id': str(new_instance['id']), 'links': [{ 'href': self.app.get_endpoint_url('compute', req, 'v2_server', instance_id=new_instance['id']), 'rel': 'self' }], 'adminPass': '', # TODO(imkarrer) - Added security_groups to make tempest pass, need real groups # noqa 'security_groups': [] } }
def get_server_details_dict(app, req, instance, is_list): image_id = utils.lookup(instance, 'blockDeviceTemplateGroup', 'globalIdentifier') tenant_id = str(instance['accountId']) client = req.sl_client vs = client['Virtual_Guest'] flavor_url = None flavor_id = 1 if is_list: tags = vs.getTagReferences(id=instance['id']) for tag in tags: if 'flavor_id' in tag['tag']['name']: try: # Try to parse the flavor id from the tag format # i.e. 'flavor_id: 2' tag_string = tag['tag']['name'] flavor_id = int(re.search(r'\d+', tag_string).group()) flavor_url = app.get_endpoint_url('compute', req, 'v2_flavor', flavor_id=flavor_id) except Exception: pass # Workaround of hardcoded ID for VS's created before flavor-id # pushed into tags if not flavor_url: flavor_url = app.get_endpoint_url('compute', req, 'v2_flavor', flavor_id=1) server_url = app.get_endpoint_url('compute', req, 'v2_server', server_id=instance['id']) task_state = None transaction = utils.lookup(instance, 'activeTransaction', 'transactionStatus', 'name') if transaction and any( ['RECLAIM' in transaction, 'TEAR_DOWN' in transaction]): task_state = 'deleting' else: task_state = transaction # Map SL Power States to OpenStack Power States power_state, status = _get_power_state_and_status(instance) addresses = {} if instance.get('primaryBackendIpAddress'): addresses['private'] = [{ 'addr': instance.get('primaryBackendIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] if instance.get('primaryIpAddress'): addresses['public'] = [{ 'addr': instance.get('primaryIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] # returning None makes tempest fail, # conditionally returning empty string for uid and zone uid = _get_user_id_from_metadata(instance) zone = utils.lookup(instance, 'datacenter', 'name') if not zone: zone = '' results = { 'id': str(instance['id']), 'accessIPv4': '', 'accessIPv6': '', 'addresses': addresses, 'created': instance['createDate'], # TODO(nbeitenmiller) - Do I need to run this through isoformat()? 'flavor': { 'id': str(flavor_id), 'links': [ { 'href': flavor_url, 'rel': 'bookmark', }, ], }, 'hostId': str(instance['id']), 'links': [{ 'href': server_url, 'rel': 'self', }], 'name': instance['hostname'], 'OS-EXT-AZ:availability_zone': zone, 'OS-EXT-STS:power_state': power_state, 'OS-EXT-STS:task_state': task_state, 'OS-EXT-STS:vm_state': instance['status']['keyName'], 'security_groups': [{ 'name': 'default' }], 'status': status, 'tenant_id': tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key or if it's stashed in userData. # Otherwise it will be ''. 'user_id': uid, 'updated': instance['modifyDate'], # TODO(imkarrer) added to make tempest pass, need real metadata 'metadata': {} } # OpenStack only supports having one SSH Key assigned to an instance if instance['sshKeys']: results['key_name'] = instance['sshKeys'][0]['label'] if image_id: results['image'] = { 'id': image_id, 'links': [ { 'href': app.get_endpoint_url('compute', req, 'v2_image', image_id=image_id), 'rel': 'self', }, ], } else: # The compute API always has an image key in the response and clients # like python-openstackclient expect this so even if we can't find the # image ID for the server we need to add an entry for image. It must # either be None or an empty string. Nova returns an empty string so # we do the same. results['image'] = '' return results
def assert_tenant(user): tenant = utils.lookup(credentials, 'auth', 'tenantId') if tenant and str(user['accountId']) != tenant: raise exceptions.Unauthorized( 'Invalid username, password or tenant id')
def get_server_details_dict(app, req, instance): image_id = lookup(instance, "blockDeviceTemplateGroup", "globalIdentifier") tenant_id = instance["accountId"] # TODO - Don't hardcode this flavor ID flavor_url = app.get_endpoint_url("compute", req, "v2_flavor", flavor_id=1) server_url = app.get_endpoint_url("compute", req, "v2_server", server_id=instance["id"]) task_state = None transaction = lookup(instance, "activeTransaction", "transactionStatus", "name") if transaction and any(["RECLAIM" in transaction, "TEAR_DOWN" in transaction]): task_state = "deleting" else: task_state = transaction # Map SL Power States to OpenStack Power States power_state = 0 status = "UNKNOWN" sl_power_state = instance["powerState"]["keyName"] if sl_power_state == "RUNNING": if transaction or not instance.get("provisionDate"): status = "BUILD" power_state = OPENSTACK_POWER_MAP["BLOCKED"] else: status = "ACTIVE" power_state = OPENSTACK_POWER_MAP["RUNNING"] elif sl_power_state == "PAUSED": status = "PAUSED" power_state = OPENSTACK_POWER_MAP["PAUSED"] elif sl_power_state in OPENSTACK_POWER_MAP: power_state = OPENSTACK_POWER_MAP[sl_power_state] elif sl_power_state == "HALTED" and instance.get("provisionDate"): status = "SHUTOFF" power_state = OPENSTACK_POWER_MAP["SHUTOFF"] elif sl_power_state == "HALTED": status = "SHUTOFF" power_state = OPENSTACK_POWER_MAP["BLOCKED"] addresses = {} if instance.get("primaryBackendIpAddress"): addresses["private"] = [ {"addr": instance.get("primaryBackendIpAddress"), "version": 4, "OS-EXT-IPS:type": "fixed"} ] if instance.get("primaryIpAddress"): addresses["public"] = [{"addr": instance.get("primaryIpAddress"), "version": 4, "OS-EXT-IPS:type": "fixed"}] # TODO - Don't hardcode this image_name = "" results = { "id": str(instance["id"]), "accessIPv4": "", "accessIPv6": "", "addresses": addresses, "created": instance["createDate"], # TODO - Do I need to run this through isoformat()? "flavor": { # TODO - Make this realistic "id": "1", "links": [{"href": flavor_url, "rel": "bookmark"}], }, "hostId": instance["id"], "links": [{"href": server_url, "rel": "self"}], "name": instance["hostname"], "OS-EXT-AZ:availability_zone": lookup(instance, "datacenter", "id"), "OS-EXT-STS:power_state": power_state, "OS-EXT-STS:task_state": task_state, "OS-EXT-STS:vm_state": instance["status"]["keyName"], "security_groups": [{"name": "default"}], "status": status, "tenant_id": tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key. Otherwise it will be None "user_id": lookup(instance, "billingItem", "orderItem", "order", "userRecordId"), "updated": instance["modifyDate"], "image_name": image_name, } # OpenStack only supports having one SSH Key assigned to an instance if instance["sshKeys"]: results["key_name"] = instance["sshKeys"][0]["label"] if image_id: results["image"] = { "id": image_id, "links": [{"href": app.get_endpoint_url("compute", req, "v2_image", image_id=image_id), "rel": "self"}], } return results
def get_new_token_v3(credentials): token_driver = identity.token_driver() token_id = utils.lookup(credentials, 'auth', 'identity', 'token', 'id') if token_id: token = identity.token_id_driver().token_from_id(token_id) LOG.debug("token details are: %s", str(token)) token_driver.validate_token(token) username = token_driver.username(token) credential = token_driver.credential(token) userinfo = {'username': username, 'auth_type': str(token['auth_type']), 'tenant_id': str(token['tenant_id']), 'expires': token['expires']} if token['auth_type'] == 'token': userinfo['tokenHash'] = credential if token['auth_type'] == 'api_key': userinfo['api_key'] = credential user = {'id': token['user_id'], 'username': username, 'accountId': token['tenant_id']} return userinfo, user username = utils.lookup(credentials, 'auth', 'passwordCredentials', 'username') credential = utils.lookup(credentials, 'auth', 'passwordCredentials', 'password') # If the 'password' is the right length, treat it as an API api_key if len(credential) == 64: endpoint = cfg.CONF['softlayer']['endpoint'] client = SoftLayer.Client(username=username, api_key=credential, endpoint_url=endpoint, proxy=cfg.CONF['softlayer']['proxy']) user = client['Account'].getCurrentUser(mask=USER_MASK) username = token_driver.username(user) return {'username': username, 'api_key': credential, 'auth_type': 'api_key', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user else: endpoint = cfg.CONF['softlayer']['endpoint'] client = SoftLayer.Client(endpoint_url=endpoint, proxy=cfg.CONF['softlayer']['proxy']) client.auth = None try: userId, tokenHash = client.authenticate_with_password(username, credential) user = client['Account'].getCurrentUser(mask=USER_MASK) username = token_driver.username(user) return {'userId': userId, 'username': username, 'tokenHash': tokenHash, 'auth_type': 'token', 'tenant_id': str(user['accountId']), 'expires': time.time() + (60 * 60 * 24)}, user except SoftLayer.SoftLayerAPIError as e: if e.faultCode == 'SoftLayer_Exception_User_Customer_LoginFailed': raise exceptions.Unauthorized(e.faultString) raise
def assert_tenant(user): tenant = lookup(creds, 'auth', 'tenantId') or lookup( creds, 'auth', 'tenantName') if tenant and str(user['accountId']) != tenant: raise Unauthorized('Invalid username, password or tenant id')
def get_server_details_dict(app, req, instance, is_list): image_id = utils.lookup(instance, 'blockDeviceTemplateGroup', 'globalIdentifier') tenant_id = instance['accountId'] client = req.env['sl_client'] vs = client['Virtual_Guest'] flavor_url = None flavor_id = 1 if is_list: tags = vs.getTagReferences(id=instance['id']) for tag in tags: if 'flavor_id' in tag['tag']['name']: try: # Try to parse the flavor id from the tag format # i.e. 'flavor_id: 2' tag_string = tag['tag']['name'] flavor_id = int(re.search(r'\d+', tag_string).group()) flavor_url = app.get_endpoint_url('compute', req, 'v2_flavor', flavor_id=flavor_id) except Exception: pass # Workaround of hardcoded ID for VS's created before flavor-id # pushed into tags if not flavor_url: flavor_url = app.get_endpoint_url('compute', req, 'v2_flavor', flavor_id=1) server_url = app.get_endpoint_url('compute', req, 'v2_server', server_id=instance['id']) task_state = None transaction = utils.lookup(instance, 'activeTransaction', 'transactionStatus', 'name') if transaction and any( ['RECLAIM' in transaction, 'TEAR_DOWN' in transaction]): task_state = 'deleting' else: task_state = transaction # Map SL Power States to OpenStack Power States power_state = 0 status = 'UNKNOWN' sl_power_state = instance['powerState']['keyName'] if sl_power_state == 'RUNNING': if transaction or not instance.get('provisionDate'): status = 'BUILD' power_state = OPENSTACK_POWER_MAP['BLOCKED'] else: status = 'ACTIVE' power_state = OPENSTACK_POWER_MAP['RUNNING'] elif sl_power_state == 'PAUSED': status = 'PAUSED' power_state = OPENSTACK_POWER_MAP['PAUSED'] elif sl_power_state in OPENSTACK_POWER_MAP: power_state = OPENSTACK_POWER_MAP[sl_power_state] elif sl_power_state == 'HALTED' and instance.get('provisionDate'): status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['SHUTOFF'] elif sl_power_state == 'HALTED': status = 'SHUTOFF' power_state = OPENSTACK_POWER_MAP['BLOCKED'] addresses = {} if instance.get('primaryBackendIpAddress'): addresses['private'] = [{ 'addr': instance.get('primaryBackendIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] if instance.get('primaryIpAddress'): addresses['public'] = [{ 'addr': instance.get('primaryIpAddress'), 'version': 4, 'OS-EXT-IPS:type': 'fixed', }] # TODO(kmcdonald) - Don't hardcode this image_name = '' results = { 'id': str(instance['id']), 'accessIPv4': '', 'accessIPv6': '', 'addresses': addresses, 'created': instance['createDate'], # TODO(nbeitenmiller) - Do I need to run this through isoformat()? 'flavor': { 'id': str(flavor_id), 'links': [ { 'href': flavor_url, 'rel': 'bookmark', }, ], }, 'hostId': instance['id'], 'links': [{ 'href': server_url, 'rel': 'self', }], 'name': instance['hostname'], 'OS-EXT-AZ:availability_zone': utils.lookup(instance, 'datacenter', 'id'), 'OS-EXT-STS:power_state': power_state, 'OS-EXT-STS:task_state': task_state, 'OS-EXT-STS:vm_state': instance['status']['keyName'], 'security_groups': [{ 'name': 'default' }], 'status': status, 'tenant_id': tenant_id, # NOTE(bodenr): userRecordId accessibility determined by permissions # of API caller's user id and api key. Otherwise it will be None 'user_id': utils.lookup(instance, 'billingItem', 'orderItem', 'order', 'userRecordId'), 'updated': instance['modifyDate'], 'image_name': image_name, } # OpenStack only supports having one SSH Key assigned to an instance if instance['sshKeys']: results['key_name'] = instance['sshKeys'][0]['label'] if image_id: results['image'] = { 'id': image_id, 'links': [ { 'href': app.get_endpoint_url('compute', req, 'v2_image', image_id=image_id), 'rel': 'self', }, ], } return results