X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fdummy%2Fdummyaggregate.py;h=fcdca5d7d603f549414f622e16fe6fb753ec6b43;hb=4a9e6751f9f396f463932133b9d62fc925a99ef6;hp=99127d7304c602379528f40558f2a8f48d0b1340;hpb=a49c0e1ae9001aa0ff22cc7262e5669db0739df5;p=sfa.git diff --git a/sfa/dummy/dummyaggregate.py b/sfa/dummy/dummyaggregate.py index 99127d73..fcdca5d7 100644 --- a/sfa/dummy/dummyaggregate.py +++ b/sfa/dummy/dummyaggregate.py @@ -1,17 +1,17 @@ -#!/usr/bin/python +#!/usr/bin/env python3 from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn from sfa.util.sfatime import utcparse, datetime_to_string from sfa.util.sfalogging import logger from sfa.rspecs.rspec import RSpec from sfa.rspecs.elements.hardware_type import HardwareType -from sfa.rspecs.elements.node import Node +from sfa.rspecs.elements.node import NodeElement from sfa.rspecs.elements.link import Link from sfa.rspecs.elements.sliver import Sliver from sfa.rspecs.elements.login import Login from sfa.rspecs.elements.location import Location from sfa.rspecs.elements.interface import Interface -from sfa.rspecs.elements.services import Services +from sfa.rspecs.elements.services import ServicesElement from sfa.rspecs.elements.pltag import PLTag from sfa.rspecs.elements.lease import Lease from sfa.rspecs.elements.granularity import Granularity @@ -19,8 +19,10 @@ from sfa.rspecs.version_manager import VersionManager from sfa.dummy.dummyxrn import DummyXrn, hostname_to_urn, hrn_to_dummy_slicename, slicename_to_hrn +from sfa.storage.model import SliverAllocation import time + class DummyAggregate: def __init__(self, driver): @@ -41,86 +43,255 @@ class DummyAggregate: if not slices: return (slice, slivers) slice = slices[0] - - # sort slivers by node id + + # sort slivers by node id slice_nodes = [] - if 'node_ids' in slice.keys(): - slice_nodes = self.driver.shell.GetNodes({'node_ids': slice['node_ids']}) + if 'node_ids' in list(slice.keys()): + slice_nodes = self.driver.shell.GetNodes( + {'node_ids': slice['node_ids']}) for node in slice_nodes: - slivers[node['node_id']] = node + slivers[node['node_id']] = node return (slice, slivers) - def get_nodes(self, slice_xrn, slice=None,slivers=[], options={}): - # if we are dealing with a slice that has no node just return - # and empty list - if slice_xrn: - if not slice or 'node_ids' not in slice.keys() or not slice['node_ids']: - return [] + def get_nodes(self, options=None): + if options is None: + options = {} + filter = {} + nodes = self.driver.shell.GetNodes(filter) + return nodes + + def get_slivers(self, urns, options=None): + if options is None: + options = {} + slice_names = set() + slice_ids = set() + node_ids = [] + for urn in urns: + xrn = DummyXrn(xrn=urn) + if xrn.type == 'sliver': + # id: slice_id-node_id + try: + sliver_id_parts = xrn.get_sliver_id_parts() + slice_id = int(sliver_id_parts[0]) + node_id = int(sliver_id_parts[1]) + slice_ids.add(slice_id) + node_ids.append(node_id) + except ValueError: + pass + else: + slice_names.add(xrn.dummy_slicename()) filter = {} - if slice and 'node_ids' in slice and slice['node_ids']: - filter['node_ids'] = slice['node_ids'] + if slice_names: + filter['slice_name'] = list(slice_names) + if slice_ids: + filter['slice_id'] = list(slice_ids) + # get slices + slices = self.driver.shell.GetSlices(filter) + if not slices: + return [] + slice = slices[0] + slice['hrn'] = DummyXrn(auth=self.driver.hrn, + slicename=slice['slice_name']).hrn + + # get sliver users + users = [] + user_ids = [] + for slice in slices: + if 'user_ids' in list(slice.keys()): + user_ids.extend(slice['user_ids']) + if user_ids: + users = self.driver.shell.GetUsers({'user_ids': user_ids}) + + # construct user key info + users_list = [] + for user in users: + name = user['email'][0:user['email'].index('@')] + user = { + 'login': slice['slice_name'], + 'user_urn': Xrn('%s.%s' % (self.driver.hrn, name), type='user').urn, + 'keys': user['keys'] + } + users_list.append(user) + if node_ids: + node_ids = [ + node_id for node_id in node_ids if node_id in slice['node_ids']] + slice['node_ids'] = node_ids + nodes_dict = self.get_slice_nodes(slice, options) + slivers = [] + for node in list(nodes_dict.values()): + node.update(slice) + sliver_hrn = '%s.%s-%s' % (self.driver.hrn, + slice['slice_id'], node['node_id']) + node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn + node['urn'] = node['sliver_id'] + node['services_user'] = users + slivers.append(node) + return slivers + + def node_to_rspec_node(self, node, options=None): + if options is None: + options = {} + rspec_node = NodeElement() + site = self.driver.testbedInfo + rspec_node['component_id'] = hostname_to_urn( + self.driver.hrn, site['name'], node['hostname']) + rspec_node['component_name'] = node['hostname'] + rspec_node['component_manager_id'] = Xrn( + self.driver.hrn, 'authority+cm').get_urn() + rspec_node['authority_id'] = hrn_to_urn(DummyXrn.site_hrn( + self.driver.hrn, site['name']), 'authority+sa') + # distinguish between Shared and Reservable nodes + rspec_node['exclusive'] = 'false' + + rspec_node['hardware_types'] = [HardwareType({'name': 'dummy-pc'}), + HardwareType({'name': 'pc'})] + if site['longitude'] and site['latitude']: + location = Location({'longitude': site['longitude'], 'latitude': site[ + 'latitude'], 'country': 'unknown'}) + rspec_node['location'] = location + return rspec_node + + def sliver_to_rspec_node(self, sliver, sliver_allocations): + rspec_node = self.node_to_rspec_node(sliver) + rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires'])) + # add sliver info + rspec_sliver = Sliver({'sliver_id': sliver['urn'], + 'name': sliver['slice_name'], + 'type': 'dummy-vserver', + 'tags': []}) + rspec_node['sliver_id'] = rspec_sliver['sliver_id'] + if sliver['urn'] in sliver_allocations: + rspec_node['client_id'] = sliver_allocations[ + sliver['urn']].client_id + if sliver_allocations[sliver['urn']].component_id: + rspec_node['component_id'] = sliver_allocations[ + sliver['urn']].component_id + rspec_node['slivers'] = [rspec_sliver] + + # slivers always provide the ssh service + login = Login({'authentication': 'ssh-keys', + 'hostname': sliver['hostname'], + 'port': '22', + 'username': sliver['slice_name'], + 'login': sliver['slice_name'] + }) + return rspec_node + + def get_slice_nodes(self, slice, options=None): + if options is None: + options = {} + nodes_dict = {} + filter = {} + if slice and slice.get('node_ids'): + filter['node_ids'] = slice['node_ids'] + else: + # there are no nodes to look up + return nodes_dict nodes = self.driver.shell.GetNodes(filter) - + for node in nodes: + nodes_dict[node['node_id']] = node + return nodes_dict + + def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations=None): + if sliver_allocations is None: + sliver_allocations = {} + if rspec_node['sliver_id'] in sliver_allocations: + # set sliver allocation and operational status + sliver_allocation = sliver_allocations[rspec_node['sliver_id']] + if sliver_allocation: + allocation_status = sliver_allocation.allocation_state + if allocation_status == 'geni_allocated': + op_status = 'geni_pending_allocation' + elif allocation_status == 'geni_provisioned': + op_status = 'geni_ready' + else: + op_status = 'geni_unknown' + else: + allocation_status = 'geni_unallocated' + else: + allocation_status = 'geni_unallocated' + op_status = 'geni_failed' + # required fields + geni_sliver = {'geni_sliver_urn': rspec_node['sliver_id'], + 'geni_expires': rspec_node['expires'], + 'geni_allocation_status': allocation_status, + 'geni_operational_status': op_status, + 'geni_error': '', + } + return geni_sliver + + def list_resources(self, version=None, options=None): + if options is None: + options = {} + + version_manager = VersionManager() + version = version_manager.get_version(version) + rspec_version = version_manager._get_version( + version.type, version.version, 'ad') + rspec = RSpec(version=rspec_version, user_options=options) + + # get nodes + nodes = self.get_nodes(options) + nodes_dict = {} + for node in nodes: + nodes_dict[node['node_id']] = node + + # convert nodes to rspec nodes rspec_nodes = [] for node in nodes: - rspec_node = Node() - # xxx how to retrieve site['login_base'] - site=self.driver.testbedInfo - rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site['name'], node['hostname']) - rspec_node['component_name'] = node['hostname'] - rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn() - rspec_node['authority_id'] = hrn_to_urn(DummyXrn.site_hrn(self.driver.hrn, site['name']), 'authority+sa') - rspec_node['exclusive'] = 'false' - rspec_node['hardware_types'] = [HardwareType({'name': 'plab-pc'}), - HardwareType({'name': 'pc'})] - # add site/interface info to nodes. - # assumes that sites, interfaces and tags have already been prepared. - if site['longitude'] and site['latitude']: - location = Location({'longitude': site['longitude'], 'latitude': site['latitude'], 'country': 'unknown'}) - rspec_node['location'] = location - - if node['node_id'] in slivers: - # add sliver info - sliver = slivers[node['node_id']] - rspec_node['client_id'] = node['hostname'] - rspec_node['slivers'] = [sliver] - - # slivers always provide the ssh service - login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22', 'username': slice['slice_name']}) - service = Services({'login': login}) - rspec_node['services'] = [service] + rspec_node = self.node_to_rspec_node(node) rspec_nodes.append(rspec_node) - return rspec_nodes - + rspec.version.add_nodes(rspec_nodes) - - def get_rspec(self, slice_xrn=None, version = None, options={}): + return rspec.toxml() + def describe(self, urns, version=None, options=None): + if options is None: + options = {} version_manager = VersionManager() version = version_manager.get_version(version) - if not slice_xrn: - rspec_version = version_manager._get_version(version.type, version.version, 'ad') + rspec_version = version_manager._get_version( + version.type, version.version, 'manifest') + rspec = RSpec(version=rspec_version, user_options=options) + + # get slivers + geni_slivers = [] + slivers = self.get_slivers(urns, options) + if slivers: + rspec_expires = datetime_to_string(utcparse(slivers[0]['expires'])) else: - rspec_version = version_manager._get_version(version.type, version.version, 'manifest') + rspec_expires = datetime_to_string(utcparse(time.time())) + rspec.xml.set('expires', rspec_expires) - slice, slivers = self.get_slice_and_slivers(slice_xrn) - rspec = RSpec(version=rspec_version, user_options=options) - if slice and 'expires' in slice: - rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires']))) - - nodes = self.get_nodes(slice_xrn, slice, slivers, options) - rspec.version.add_nodes(nodes) - # add sliver defaults - default_sliver = slivers.get(None, []) - if default_sliver: - default_sliver_attribs = default_sliver.get('tags', []) - for attrib in default_sliver_attribs: - logger.info(attrib) - rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value']) - - return rspec.toxml() + # lookup the sliver allocations + geni_urn = urns[0] + sliver_ids = [sliver['sliver_id'] for sliver in slivers] + constraint = SliverAllocation.sliver_id.in_(sliver_ids) + sliver_allocations = self.driver.api.dbsession().query( + SliverAllocation).filter(constraint) + sliver_allocation_dict = {} + for sliver_allocation in sliver_allocations: + geni_urn = sliver_allocation.slice_urn + sliver_allocation_dict[ + sliver_allocation.sliver_id] = sliver_allocation + # add slivers + nodes_dict = {} + for sliver in slivers: + nodes_dict[sliver['node_id']] = sliver + rspec_nodes = [] + for sliver in slivers: + rspec_node = self.sliver_to_rspec_node( + sliver, sliver_allocation_dict) + rspec_nodes.append(rspec_node) + geni_sliver = self.rspec_node_to_geni_sliver( + rspec_node, sliver_allocation_dict) + geni_slivers.append(geni_sliver) + rspec.version.add_nodes(rspec_nodes) + return {'geni_urn': geni_urn, + 'geni_rspec': rspec.toxml(), + 'geni_slivers': geni_slivers}