help="type filter ([all]|user|slice|authority|node|aggregate)",
choices=("all", "user", "slice", "authority", "node", "aggregate"),
default="all")
+ if command in ("show"):
+ parser.add_option("-k","--key",dest="keys",action="append",default=[],
+ help="specify specific keys to be displayed from record")
if command in ("resources"):
# rspec version
parser.add_option("-r", "--rspec-version", dest="rspec_version", default="SFA 1",
def print_help (self):
+ print "==================== Generic sfi usage"
self.sfi_parser.print_help()
+ print "==================== Specific command usage"
self.command_parser.print_help()
#
self.dispatch(command, command_options, command_args)
except KeyError:
self.logger.critical ("Unknown command %s"%command)
- raise
sys.exit(1)
-
+
return
####################
record_dicts = filter_records(options.type, record_dicts)
if not record_dicts:
self.logger.error("No record of type %s"% options.type)
+ return
+ # user has required to focus on some keys
+ if options.keys:
+ def project (record):
+ projected={}
+ for key in options.keys:
+ try: projected[key]=record[key]
+ except: pass
+ return projected
+ record_dicts = [ project (record) for record in record_dicts ]
records = [ Record(dict=record_dict) for record_dict in record_dicts ]
for record in records:
if (options.format == "text"): record.dump(sort=True)
renew slice (RenewSliver)
"""
server = self.sliceapi()
+ if len(args) != 2:
+ self.print_help()
+ sys.exit(1)
+ [ slice_hrn, input_time ] = args
# slice urn
- slice_hrn = args[0]
slice_urn = hrn_to_urn(slice_hrn, 'slice')
+ # time: don't try to be smart on the time format, server-side will
# creds
slice_cred = self.slice_credential_string(args[0])
creds = [slice_cred]
if options.delegate:
delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
creds.append(delegated_cred)
- # time
- time = args[1]
# options and call_id when supported
api_options = {}
api_options['call_id']=unique_call_id()
- result = server.RenewSliver(slice_urn, creds, time, *self.ois(server,api_options))
+ result = server.RenewSliver(slice_urn, creds, input_time, *self.ois(server,api_options))
value = ReturnValue.get_value(result)
if self.options.raw:
save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
import sfa.federica.fddriver
+# the federica flavour behaves like pl, except for
+# the driver
+
class fd (pl):
-# the max flavour behaves like pl, except for
-# the aggregate
def driver_class (self) :
return sfa.federica.fddriver.FdDriver
try:
result=server.RenewSliver(xrn, creds, expiration_time, options)
if type(result)!=dict:
- result = {"code": {"geni_code": 0}, value: result}
- result["aggregate"] = aggregate
+ result = {'code': {'geni_code': 0}, 'value': result}
+ result['aggregate'] = aggregate
return result
except:
logger.log_exc('Something wrong in _RenewSliver with URL %s'%server.url)
- return {"aggregate": aggregate, "exc_info": traceback.format_exc(), "code": {"geni_code": -1}, "value": False, "output": ""}
+ return {'aggregate': aggregate, 'exc_info': traceback.format_exc(),
+ 'code': {'geni_code': -1},
+ 'value': False, 'output': ""}
(hrn, urn_type) = urn_to_hrn(xrn)
# get the callers hrn
results = threads.get_results()
geni_code = 0
- geni_output = ",".join([x.get("output","") for x in results])
- geni_value = reduce (lambda x,y: x and y, [result.get("value",False) for result in results], True)
+ geni_output = ",".join([x.get('output',"") for x in results])
+ geni_value = reduce (lambda x,y: x and y, [result.get('value',False) for result in results], True)
for agg_result in results:
- agg_geni_code = agg_result["code"].get("geni_code",0)
+ agg_geni_code = agg_result['code'].get('geni_code',0)
if agg_geni_code:
geni_code = agg_geni_code
- results = {"aggregates": results, "code": {"geni_code": geni_code}, "value": geni_value, "output": geni_output}
+ results = {'aggregates': results, 'code': {'geni_code': geni_code}, 'value': geni_value, 'output': geni_output}
return results
# mmh, it is expected that all results carry the same urn
overall['geni_urn'] = results[0]['geni_urn']
- overall['pl_login'] = results[0]['pl_login']
+ overall['pl_login'] = None
+ for result in results:
+ if result.get('pl_login'):
+ overall['pl_login'] = result['pl_login']
+ break
+ elif isinstance(result.get('value'), dict) and result['value'].get('pl_login'):
+ overall['pl_login'] = result['value']['pl_login']
+ break
# append all geni_resources
overall['geni_resources'] = \
reduce (lambda x,y: x+y, [ result['geni_resources'] for result in results] , [])
raise InsufficientRights('Renewsliver: Credential expires before requested expiration time')
if requested_time > datetime.datetime.utcnow() + datetime.timedelta(days=max_renew_days):
raise Exception('Cannot renew > %s days from now' % max_renew_days)
- return self.api.manager.RenewSliver(self.api, slice_xrn, valid_creds, expiration_time, options)
+ return self.api.manager.RenewSliver(self.api, slice_xrn, valid_creds, expiration_time, options)
from sfa.util.defaultdict import defaultdict
from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
from sfa.util.xrn import Xrn, hrn_to_urn, get_leaf, urn_to_sliver_id
+from sfa.planetlab.plxrn import PlXrn
+from sfa.openstack.osxrn import hrn_to_os_slicename
from sfa.util.cache import Cache
from sfa.trust.credential import Credential
# used to be used in get_ticket
if type == 'slice':
# add slice description, name, researchers, PI
- name = Xrn(hrn).get_leaf()
+ name = hrn_to_os_slicename(hrn)
researchers = sfa_record.get('researchers', [])
pis = sfa_record.get('pis', [])
project_manager = None
elif type == "slice":
# can update project manager and description
- name = Xrn(hrn).get_leaf()
+ name = hrn_to_os_slicename(hrn)
researchers = sfa_record.get('researchers', [])
pis = sfa_record.get('pis', [])
project_manager = None
##########
def remove (self, sfa_record):
type=sfa_record['type']
- name = Xrn(sfa_record['hrn']).get_leaf()
if type == 'user':
+ name = Xrn(sfa_record['hrn']).get_leaf()
if self.shell.auth_manager.get_user(name):
self.shell.auth_manager.delete_user(name)
elif type == 'slice':
+ name = hrn_to_os_slicename(sfa_record['hrn'])
if self.shell.auth_manager.get_project(name):
self.shell.auth_manager.delete_project(name)
return True
records = [records]
for record in records:
- name = Xrn(record['hrn']).get_leaf()
os_record = None
if record['type'] == 'user':
+ name = Xrn(record['hrn']).get_leaf()
os_record = self.shell.auth_manager.get_user(name)
projects = self.shell.db.project_get_by_user(name)
record['slices'] = [self.hrn + "." + proj.name for \
record['roles'] = self.shell.db.user_get_roles(name)
keys = self.shell.db.key_pair_get_all_by_user(name)
record['keys'] = [key.public_key for key in keys]
- elif record['type'] == 'slice':
+ elif record['type'] == 'slice':
+ name = hrn_to_os_slicename(record['hrn'])
os_record = self.shell.auth_manager.get_project(name)
record['description'] = os_record.description
record['PI'] = [self.hrn + "." + os_record.project_manager.name]
def sliver_status (self, slice_urn, slice_hrn):
# find out where this slice is currently running
- project_name = Xrn(slice_urn).get_leaf()
+ project_name = hrn_to_os_slicename(slice_hrn)
project = self.shell.auth_manager.get_project(project_name)
instances = self.shell.db.instance_get_all_by_project(project_name)
if len(instances) == 0:
def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
- project_name = get_leaf(slice_hrn)
+ project_name = hrn_to_os_slicename(slice_hrn)
aggregate = OSAggregate(self)
# parse rspec
rspec = RSpec(rspec_string)
def delete_sliver (self, slice_urn, slice_hrn, creds, options):
# we need to do this using the context of one of the slice users
- project_name = Xrn(slice_urn).get_leaf()
+ project_name = hrn_to_os_slicename(slice_hrn)
self.euca_shell.init_context(project_name)
- name = OSXrn(xrn=slice_urn).name
aggregate = OSAggregate(self)
- return aggregate.delete_instances(name)
+ return aggregate.delete_instances(project_name)
def update_sliver(self, slice_urn, slice_hrn, rspec, creds, options):
- name = OSXrn(xrn=slice_urn).name
+ name = hrn_to_os_slicename(slice_hrn)
aggregate = OSAggregate(self)
return aggregate.update_instances(name)
from sfa.rspecs.elements.login import Login
from sfa.rspecs.elements.disk_image import DiskImage
from sfa.rspecs.elements.services import Services
+from sfa.rspecs.elements.interface import Interface
from sfa.util.xrn import Xrn
-from sfa.util.osxrn import OSXrn
+from sfa.planetlab.plxrn import PlXrn
+from sfa.openstack.osxrn import OSXrn, hrn_to_os_slicename
from sfa.rspecs.version_manager import VersionManager
from sfa.openstack.image import ImageManager
from sfa.openstack.security_group import SecurityGroup
from sfa.util.sfalogging import logger
+def pubkeys_to_user_data(pubkeys):
+ user_data = "#!/bin/bash\n\n"
+ for pubkey in pubkeys:
+ pubkey = pubkey.replace('\n', '')
+ user_data += "echo %s >> /root/.ssh/authorized_keys" % pubkey
+ user_data += "\n"
+ user_data += "echo >> /root/.ssh/authorized_keys"
+ user_data += "\n"
+ return user_data
+
def instance_to_sliver(instance, slice_xrn=None):
# should include?
# * instance.image_ref
rspec.version.add_nodes(nodes)
return rspec.toxml()
+ def get_availability_zones(self):
+ try:
+ # pre essex releases
+ zones = self.driver.shell.db.zone_get_all()
+ except:
+ # essex release
+ zones = self.driver.shell.db.dnsdomain_list()
+
+ if not zones:
+ zones = ['cloud']
+ else:
+ zones = [zone.name for zone in zones]
+ return zones
+
def get_slice_nodes(self, slice_xrn):
image_manager = ImageManager(self.driver)
- name = OSXrn(xrn = slice_xrn).name
+
+ zones = self.get_availability_zones()
+ name = hrn_to_os_slicename(slice_xrn)
instances = self.driver.shell.db.instance_get_all_by_project(name)
rspec_nodes = []
for instance in instances:
rspec_node = Node()
- xrn = OSXrn(instance.hostname, 'node')
- rspec_node['component_id'] = xrn.urn
- rspec_node['component_name'] = xrn.name
+ interfaces = []
+ for fixed_ip in instance.fixed_ips:
+ if_xrn = PlXrn(auth=self.driver.hrn,
+ interface='node%s:eth0' % (instance.hostname))
+ interface = Interface({'component_id': if_xrn.urn})
+ interface['ips'] = [{'address': fixed_ip['address'],
+ 'netmask': fixed_ip['network'].netmask,
+ 'type': 'ipv4'}]
+ interface['floating_ips'] = []
+ for floating_ip in fixed_ip.floating_ips:
+ interface['floating_ips'].append(floating_ip.address)
+ interfaces.append(interface)
+ if instance.availability_zone:
+ node_xrn = OSXrn(instance.availability_zone, 'node')
+ else:
+ node_xrn = OSXrn('cloud', 'node')
+
+ rspec_node['component_id'] = node_xrn.urn
+ rspec_node['component_name'] = node_xrn.name
rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
sliver = instance_to_sliver(instance)
disk_image = image_manager.get_disk_image(instance.image_ref)
sliver['disk_image'] = [disk_image.to_rspec_object()]
rspec_node['slivers'] = [sliver]
+ rspec_node['interfaces'] = interfaces
+ # slivers always provide the ssh service
+ rspec_node['services'] = []
+ for interface in interfaces:
+ if 'floating_ips' in interface:
+ for hostname in interface['floating_ips']:
+ login = Login({'authentication': 'ssh-keys',
+ 'hostname': hostname,
+ 'port':'22', 'username': 'root'})
+ service = Services({'login': login})
+ rspec_node['services'].append(service)
rspec_nodes.append(rspec_node)
return rspec_nodes
def get_aggregate_nodes(self):
-
- zones = self.driver.shell.db.zone_get_all()
- if not zones:
- zones = ['cloud']
- else:
- zones = [zone.name for zone in zones]
-
+ zones = self.get_availability_zones()
# available sliver/instance/vm types
- instances = self.driver.shell.db.instance_type_get_all().values()
+ instances = self.driver.shell.db.instance_type_get_all()
+ if isinstance(instances, dict):
+ instances = instances.values()
# available images
image_manager = ImageManager(self.driver)
disk_images = image_manager.get_available_disk_images()
username = Xrn(user['urn']).get_leaf()
try:
self.driver.shell.auth_manager.get_user(username)
- except nova.exception.UserNotFound:
+ except UserNotFound:
self.driver.shell.auth_manager.create_user(username)
self.verify_user_keys(username, user['keys'], options)
# get requested slivers
rspec = RSpec(rspec)
- user_data = "\n".join(pubkeys)
+ user_data = pubkeys_to_user_data(pubkeys)
requested_instances = defaultdict(list)
# iterate over clouds/zones/nodes
for node in rspec.version.get_nodes_with_slivers():
--- /dev/null
+import re
+from sfa.util.xrn import Xrn
+from sfa.util.config import Config
+
+def hrn_to_os_slicename(hrn):
+ return OSXrn(xrn=hrn, type='slice').get_slicename()
+
+class OSXrn(Xrn):
+
+ def __init__(self, name=None, type=None, **kwds):
+
+ config = Config()
+ if name is not None:
+ self.type = type
+ self.hrn = config.SFA_INTERFACE_HRN + "." + name
+ self.hrn_to_urn()
+ else:
+ Xrn.__init__(self, **kwds)
+
+ self.name = self.get_name()
+
+ def get_name(self):
+ self._normalize()
+ leaf = self.leaf
+ sliver_id_parts = leaf.split(':')
+ name = sliver_id_parts[0]
+ name = re.sub('[^a-zA-Z0-9_]', '', name)
+ return name
+
+
+ def get_slicename(self):
+ self._normalize()
+ slicename = self.hrn
+ slicename = slicename.split(':')[0]
+ slicename = re.sub('[\.]', '_', slicename)
+ return slicename
+
+
filter.update({'name':slice['name']})
return_fields = ['lease_id', 'hostname', 'site_id', 'name', 't_from', 't_until']
leases = self.driver.shell.GetLeases(filter)
+ grain = self.driver.shell.GetLeaseGranularity()
site_ids = []
for lease in leases:
slice_hrn = slicename_to_hrn(self.driver.hrn, lease['name'])
slice_urn = hrn_to_urn(slice_hrn, 'slice')
rspec_lease['slice_id'] = slice_urn
- rspec_lease['t_from'] = lease['t_from']
- rspec_lease['t_until'] = lease['t_until']
+ rspec_lease['start_time'] = lease['t_from']
+ rspec_lease['duration'] = (lease['t_until'] - lease['t_from']) / grain
rspec_leases.append(rspec_lease)
return rspec_leases
requested_lease = {}
if not lease.get('lease_id'):
requested_lease['hostname'] = xrn_to_hostname(lease.get('component_id').strip())
- requested_lease['t_from'] = lease.get('t_from')
- requested_lease['t_until'] = lease.get('t_until')
+ requested_lease['start_time'] = lease.get('start_time')
+ requested_lease['duration'] = lease.get('duration')
else:
kept_leases.append(int(lease['lease_id']))
if requested_lease.get('hostname'):
def verify_slice_leases(self, slice, requested_leases, kept_leases, peer):
leases = self.driver.shell.GetLeases({'name':slice['name']}, ['lease_id'])
+ grain = self.driver.shell.GetLeaseGranularity()
current_leases = [lease['lease_id'] for lease in leases]
deleted_leases = list(set(current_leases).difference(kept_leases))
self.driver.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
deleted=self.driver.shell.DeleteLeases(deleted_leases)
for lease in requested_leases:
- added=self.driver.shell.AddLeases(lease['hostname'], slice['name'], int(lease['t_from']), int(lease['t_until']))
+ added=self.driver.shell.AddLeases(lease['hostname'], slice['name'], int(lease['start_time']), int(lease['duration']) * grain + int(lease['start_time']))
except:
logger.log_exc('Failed to add/remove slice leases')
'lease_id',
'component_id',
'slice_id'
- 't_from',
- 't_until',
+ 'start_time',
+ 'duration',
]
--- /dev/null
+from sfa.util.xrn import Xrn
+from sfa.util.xml import XpathFilter
+from sfa.rspecs.elements.interface import Interface
+
+class PGv2Interface:
+
+ @staticmethod
+ def add_interfaces(xml, interfaces):
+ if isinstance(interfaces, list):
+ for interface in interfaces:
+ if_elem = xml.add_instance('interface', interface, ['component_id', 'client_id'])
+ ips = interface.get('ips', [])
+ for ip in ips:
+ if_elem.add_instance('ip', {'address': ip.get('address'),
+ 'netmask': ip.get('netmask'),
+ 'type': ip.get('type')})
+
+ @staticmethod
+ def get_interfaces(xml):
+ pass
from sfa.rspecs.elements.pltag import PLTag
from sfa.rspecs.elements.versions.pgv2Services import PGv2Services
from sfa.rspecs.elements.versions.pgv2SliverType import PGv2SliverType
+from sfa.rspecs.elements.versions.pgv2Interface import PGv2Interface
from sfa.planetlab.plxrn import xrn_to_hostname
if node.get('location'):
node_elem.add_instance('location', node['location'], Location.fields)
# set interfaces
- if node.get('interfaces'):
- for interface in node.get('interfaces', []):
- node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
+ PGv2Interface.add_interfaces(node_elem, node.get('interfaces'))
+ #if node.get('interfaces'):
+ # for interface in node.get('interfaces', []):
+ # node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
# set available element
if node.get('boot_state'):
if node.get('boot_state').lower() == 'boot':
lease_elems = []
for lease in leases:
- lease_fields = ['lease_id', 'component_id', 'slice_id', 't_from', 't_until']
+ lease_fields = ['lease_id', 'component_id', 'slice_id', 'start_time', 'duration']
lease_elem = network_elem.add_instance('lease', lease, lease_fields)
lease_elems.append(lease_elem)
lease['lease_id'] = lease_elem.attrib['lease_id']
lease['component_id'] = lease_elem.attrib['component_id']
lease['slice_id'] = lease_elem.attrib['slice_id']
- lease['t_from'] = lease_elem.attrib['t_from']
- lease['t_until'] = lease_elem.attrib['t_until']
+ lease['start_time'] = lease_elem.attrib['start_time']
+ lease['duration'] = lease_elem.attrib['duration']
leases.append(lease)
return leases
metadata=MetaData()
-# this is needed my migrate so it can locate 'records.record_id'
+# this is needed by migrate so it can locate 'records.record_id'
records = \
Table ( 'records', metadata,
Column ('record_id', Integer, primary_key=True),
def validate_datetime (self, key, incoming):
if isinstance (incoming, datetime): return incoming
elif isinstance (incoming, (int,float)):return datetime.fromtimestamp (incoming)
+ else: logger.info("Cannot validate datetime for key %s with input %s"%\
+ (key,incoming))
@validates ('date_created')
def validate_date_created (self, key, incoming): return self.validate_datetime (key, incoming)
auth_record = dbsession.query(RegAuthority).filter_by(hrn=authority_hrn).first()
return auth_record.reg_pis
+ @validates ('expires')
+ def validate_expires (self, key, incoming): return self.validate_datetime (key, incoming)
####################
class RegNode (RegRecord):
def add_request_context_to_rspec(self, doc):
p = doc.xpathNewContext()
- context = p.xpathEval("//RSpec")
- if (not context):
+ context = p.xpathEval("//*")
+ if not context or context[0].name not in ['RSpec', 'rspec']:
raise Exception('Request is not an rspec')
else:
# Add the request context
def add_rule_context_to_rspec(self, doc):
p = doc.xpathNewContext()
- context = p.xpathEval("//RSpec")
- if (not context):
+ context = p.xpathEval("//*")
+ if not context or context[0].name not in ['RSpec', 'rspec']:
raise Exception('Request is not an rspec')
else:
# Add the request context