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
from sfa.dummy.dummyxrn import DummyXrn, hostname_to_urn, hrn_to_dummy_slicename, slicename_to_hrn
+from sfa.storage.alchemy import dbsession
+from sfa.storage.model import SliverAllocation
import time
class DummyAggregate:
slice = slices[0]
# sort slivers by node id
- slice_nodes = self.driver.shell.GetNodes({'node_ids': slice['node_ids']})
+ slice_nodes = []
+ if 'node_ids' in slice.keys():
+ slice_nodes = self.driver.shell.GetNodes({'node_ids': slice['node_ids']})
for node in slice_nodes:
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 not slice['node_ids']:
- return []
+ def get_nodes(self, options={}):
+ filter = {}
+ nodes = self.driver.shell.GetNodes(filter)
+ return nodes
+
+ def get_slivers(self, urns, 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:
+ 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 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={}):
+ 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={}):
+ 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 = {}):
+ 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={}):
+
+ 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={}):
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 = 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}