%define name sfa
%define version 3.1
-%define taglevel 5
+%define taglevel 9
%define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
%global python_sitearch %( python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)" )
#[ "$1" -ge "1" ] && service sfa-cm restart || :
%changelog
+* Mon Jul 21 2014 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-9
+- Register can change the user keys using 'reg-keys' as well as 'keys'
+- also accept a single string rather than a list of keys
+- remove 'geni_api' from the registry GetVersion (which is not based on geni anymore)
+- bump the 'sfa' tag in the same registry GetVersion to 3
+- remove all mutable used as default arguments
+
+* Thu Jun 05 2014 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-8
+- bugfix, sfi remove was broken
+
+* Wed Jun 04 2014 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-7
+- sfi return code should be more meaningful - not yet for all commands though
+- DEFAULT_CREDENTIAL_LIFETIME now 28 days (was 31)
+- dropped support for legacy credentials
+- bugfix: short-lived credentials triggered a bug with UTC translated into localtime
+- further minor cleanup of timestamp formats
+
+* Mon Jun 02 2014 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-6
+- iotlab driver: Allocate uses OAR
+- iotlab driver: using actual_caller_hrn
+
* Thu May 29 2014 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-5
- Slice Manager is down by default
- sfi renew -l/--as-long-as-possible and e.g. sfi renew <> +2[d|w|m]
pubkey = open(key, 'r').read()
except IOError:
pubkey = key
- record_dict['keys'] = [pubkey]
+ record_dict['reg-keys'] = [pubkey]
if slices:
record_dict['slices'] = slices
if researchers:
pubkey = options.key
if not check_ssh_key (pubkey):
raise SfaInvalidArgument(name='key',msg="Could not find file, or wrong key format")
- record_dict['keys'] = [pubkey]
+ record_dict['reg-keys'] = [pubkey]
if hasattr(options, 'slices') and options.slices:
record_dict['slices'] = options.slices
if hasattr(options, 'reg_researchers') and options.reg_researchers is not None:
self.logger.debug("Command=%s" % self.command)
try:
- self.dispatch(command, command_options, command_args)
+ retcod = self.dispatch(command, command_options, command_args)
except SystemExit:
return 1
except:
self.logger.log_exc ("sfi command %s failed"%command)
return 1
-
- return 0
+ return retcod
####################
def read_config(self):
sys.exit(1)
+ # helper function to analyze raw output
+ # for main : return 0 if everything is fine, something else otherwise (mostly 1 for now)
+ def success (self, raw):
+ return_value=ReturnValue (raw)
+ output=ReturnValue.get_output(return_value)
+ # means everything is fine
+ if not output:
+ return 0
+ # something went wrong
+ print 'ERROR:',output
+ return 1
+
#==========================================================================
# Following functions implement the commands
#
varname="%s_%s"%(section.upper(),name.upper())
value=getattr(self.config_instance,varname)
print "%-20s = %s"%(name,value)
+ # xxx should analyze result
+ return 0
@declare_command("","")
def version(self, options, args):
else:
pprinter = PrettyPrinter(indent=4)
pprinter.pprint(version)
+ # xxx should analyze result
+ return 0
@declare_command("authority","")
def list(self, options, args):
terminal_render (list, options)
if options.file:
save_records_to_file(options.file, list, options.fileformat)
- return
+ # xxx should analyze result
+ return 0
@declare_command("name","")
def show(self, options, args):
else: print record.save_as_xml()
if options.file:
save_records_to_file(options.file, record_dicts, options.fileformat)
- return
+ # xxx should analyze result
+ return 0
# this historically was named 'add', it is now 'register' with an alias for legacy
@declare_command("[xml-filename]","",['add'])
record_dict['first_name'] = record_dict['hrn']
if 'last_name' not in record_dict:
record_dict['last_name'] = record_dict['hrn']
- return self.registry().Register(record_dict, auth_cred)
+ register = self.registry().Register(record_dict, auth_cred)
+ # xxx looks like the result here is not ReturnValue-compatible
+ #return self.success (register)
+ # xxx should analyze result
+ return 0
@declare_command("[xml-filename]","")
def update(self, options, args):
raise "unknown record type" + record_dict['type']
if options.show_credential:
show_credentials(cred)
- return self.registry().Update(record_dict, cred)
+ update = self.registry().Update(record_dict, cred)
+ # xxx looks like the result here is not ReturnValue-compatible
+ #return self.success(update)
+ # xxx should analyze result
+ return 0
@declare_command("hrn","")
def remove(self, options, args):
type = '*'
if options.show_credential:
show_credentials(auth_cred)
- return self.registry().Remove(hrn, auth_cred, type)
+ remove = self.registry().Remove(hrn, auth_cred, type)
+ # xxx looks like the result here is not ReturnValue-compatible
+ #return self.success (remove)
+ # xxx should analyze result
+ return 0
# ==================================================================
# Slice-related commands
api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'}
else:
api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'}
- result = server.ListResources (creds, api_options)
- value = ReturnValue.get_value(result)
+ list_resources = server.ListResources (creds, api_options)
+ value = ReturnValue.get_value(list_resources)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(list_resources, self.options.raw, self.options.rawformat, self.options.rawbanner)
if options.file is not None:
save_rspec_to_file(value, options.file)
if (self.options.raw is None) and (options.file is None):
display_rspec(value, options.format)
-
- return
+ return self.success(list_resources)
@declare_command("slice_hrn","")
def describe(self, options, args):
api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'}
urn = Xrn(args[0], type='slice').get_urn()
remove_none_fields(api_options)
- result = server.Describe([urn], creds, api_options)
- value = ReturnValue.get_value(result)
+ describe = server.Describe([urn], creds, api_options)
+ value = ReturnValue.get_value(describe)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(describe, self.options.raw, self.options.rawformat, self.options.rawbanner)
if options.file is not None:
save_rspec_to_file(value['geni_rspec'], options.file)
if (self.options.raw is None) and (options.file is None):
display_rspec(value['geni_rspec'], options.format)
-
- return
+ return self.success (describe)
@declare_command("slice_hrn [<sliver_urn>...]","")
def delete(self, options, args):
api_options ['call_id'] = unique_call_id()
if options.show_credential:
show_credentials(creds)
- result = server.Delete(sliver_urns, creds, *self.ois(server, api_options ) )
- value = ReturnValue.get_value(result)
+ delete = server.Delete(sliver_urns, creds, *self.ois(server, api_options ) )
+ value = ReturnValue.get_value(delete)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(delete, self.options.raw, self.options.rawformat, self.options.rawbanner)
else:
print value
- return value
+ return self.success (delete)
@declare_command("slice_hrn rspec","")
def allocate(self, options, args):
api_options['sfa_users'] = sfa_users
api_options['geni_users'] = geni_users
- result = server.Allocate(slice_urn, creds, rspec, api_options)
- value = ReturnValue.get_value(result)
+ allocate = server.Allocate(slice_urn, creds, rspec, api_options)
+ value = ReturnValue.get_value(allocate)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(allocate, self.options.raw, self.options.rawformat, self.options.rawbanner)
if options.file is not None:
save_rspec_to_file (value['geni_rspec'], options.file)
if (self.options.raw is None) and (options.file is None):
print value
- return value
-
+ return self.success(allocate)
@declare_command("slice_hrn [<sliver_urn>...]","")
def provision(self, options, args):
users = pg_users_arg(user_records)
api_options['geni_users'] = users
- result = server.Provision(sliver_urns, creds, api_options)
- value = ReturnValue.get_value(result)
+ provision = server.Provision(sliver_urns, creds, api_options)
+ value = ReturnValue.get_value(provision)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(provision, self.options.raw, self.options.rawformat, self.options.rawbanner)
if options.file is not None:
save_rspec_to_file (value['geni_rspec'], options.file)
if (self.options.raw is None) and (options.file is None):
print value
- return value
+ return self.success(provision)
@declare_command("slice_hrn","")
def status(self, options, args):
api_options['call_id']=unique_call_id()
if options.show_credential:
show_credentials(creds)
- result = server.Status([slice_urn], creds, *self.ois(server,api_options))
- value = ReturnValue.get_value(result)
+ status = server.Status([slice_urn], creds, *self.ois(server,api_options))
+ value = ReturnValue.get_value(status)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(status, self.options.raw, self.options.rawformat, self.options.rawbanner)
else:
print value
- # Thierry: seemed to be missing
- return value
+ return self.success (status)
@declare_command("slice_hrn [<sliver_urn>...] action","")
def action(self, options, args):
delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
creds.append(delegated_cred)
- result = server.PerformOperationalAction(sliver_urns, creds, action , api_options)
- value = ReturnValue.get_value(result)
+ perform_action = server.PerformOperationalAction(sliver_urns, creds, action , api_options)
+ value = ReturnValue.get_value(perform_action)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(perform_action, self.options.raw, self.options.rawformat, self.options.rawbanner)
else:
print value
- return value
+ return self.success (perform_action)
@declare_command("slice_hrn [<sliver_urn>...] time",
"\n".join(["sfi renew onelab.ple.heartbeat 2015-04-31",
api_options['geni_extend_alap']=True
if options.show_credential:
show_credentials(creds)
- result = server.Renew(sliver_urns, creds, input_time, *self.ois(server,api_options))
- value = ReturnValue.get_value(result)
+ renew = server.Renew(sliver_urns, creds, input_time, *self.ois(server,api_options))
+ value = ReturnValue.get_value(renew)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(renew, self.options.raw, self.options.rawformat, self.options.rawbanner)
else:
print value
- return value
-
+ return self.success(renew)
@declare_command("slice_hrn","")
def shutdown(self, options, args):
# creds
slice_cred = self.slice_credential(slice_hrn)
creds = [slice_cred]
- result = server.Shutdown(slice_urn, creds)
- value = ReturnValue.get_value(result)
+ shutdown = server.Shutdown(slice_urn, creds)
+ value = ReturnValue.get_value(shutdown)
if self.options.raw:
- save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner)
+ save_raw_to_file(shutdown, self.options.raw, self.options.rawformat, self.options.rawbanner)
else:
print value
- return value
-
+ return self.success (shutdown)
@declare_command("[name]","")
def gid(self, options, args):
filename = os.sep.join([self.options.sfi_dir, '%s.gid' % target_hrn])
self.logger.info("writing %s gid to %s" % (target_hrn, filename))
GID(string=gid).save_to_file(filename)
+ # xxx should analyze result
+ return 0
####################
@declare_command("to_hrn","""$ sfi delegate -u -p -s ple.inria.heartbeat -s ple.inria.omftest ple.upmc.slicebrowser
# it is probably not helpful as people would not
# need to run 'sfi delegate' at all anymore
if count_success != count_all: sys.exit(1)
- return
+ # xxx should analyze result
+ return 0
@declare_command("cred","")
def trusted(self, options, args):
cert = Certificate(string=trusted_cert)
self.logger.debug('Sfi.trusted -> %r'%cert.get_subject())
print "Certificate:\n%s\n\n"%trusted_cert
- return
-
+ # xxx should analyze result
+ return 0
return rspec_node
- def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+ def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations=None):
"""Makes a geni sliver structure from all the nodes allocated
to slivers in the sliver_allocations dictionary. Returns the states
of the sliver.
.. seealso:: node_to_rspec_node
"""
+ 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']]
- def get_slivers(self, urns, options={}):
+ def get_slivers(self, urns, options=None):
"""Get slivers of the given slice urns. Slivers contains slice, node and
user information.
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
"""
-
+ if options is None: options={}
slice_ids = set()
node_ids = []
return slivers
- def list_resources(self, version = None, options={}):
+ def list_resources(self, version = None, options=None):
"""
Returns an advertisement Rspec of available resources at this
aggregate. This Rspec contains a resource listing along with their
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#ListResources
"""
+ if options is None: options={}
+
version_manager = VersionManager()
version = version_manager.get_version(version)
rspec_version = version_manager._get_version(version.type,
return rspec.toxml()
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, version=None, options=None):
"""
Retrieve a manifest RSpec describing the resources contained by the
named entities, e.g. a single slice or a set of the slivers in a slice.
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
"""
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
rspec_version = version_manager._get_version(
- def delete(self, slice_urns, options={}):
+ def delete(self, slice_urns, options=None):
"""
Deletes the lease associated with the slice hrn and the credentials
if the slice belongs to iotlab. Answer to DeleteSliver.
.. note:: creds are unused, and are not used either in the dummy driver
delete_sliver .
"""
+ if options is None: options={}
# collect sliver ids so we can update sliver allocation states after
# we remove the slivers.
aggregate = CortexlabAggregate(self)
# first 2 args are None in case of resource discovery
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
aggregate = CortexlabAggregate(self)
rspec = aggregate.list_resources(version=version, options=options)
return rspec
- def describe(self, urns, version, options={}):
+ def describe(self, urns, version, options=None):
+ if options is None: options={}
aggregate = CortexlabAggregate(self)
return aggregate.describe(urns, version=version, options=options)
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
aggregate = CortexlabAggregate(self)
desc = aggregate.describe(urns, version='GENI 3')
status = {'geni_urn': desc['geni_urn'],
return status
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
xrn = Xrn(urn)
aggregate = CortexlabAggregate(self)
return aggregate.describe([xrn.get_urn()], version=rspec.version)
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
# update users
slices = CortexlabSlices(self)
aggregate = CortexlabAggregate(self)
return sfa_slice
- def verify_persons(self, slice_hrn, slice_record, users, options={}):
+ def verify_persons(self, slice_hrn, slice_record, users, options=None):
"""Ensures the users in users list exist and are enabled in LDAP. Adds
person if needed(AddPerson).
"""
+ if options is None: options={}
logger.debug("CortexlabSlices \tverify_persons \tslice_hrn %s \
\t slice_record %s\r\n users %s \t "
return added_persons
- def verify_keys(self, persons, users, peer, options={}):
+ def verify_keys(self, persons, users, peer, options=None):
"""
.. warning:: unused
"""
+ if options is None: options={}
# existing keys
key_ids = []
for person in persons:
slices_list = []
for i in range(1,3):
- slice = {'slice_name': 'slice'+str(i), 'user_ids': range(i,4,2), 'slice_id': i, 'node_ids': range(i,10,2), 'enabled': True, 'expires': int(time.time())+60*60*24*30}
+ slice = {'slice_name': 'slice'+str(i),
+ 'user_ids': range(i,4,2),
+ 'slice_id': i,
+ 'node_ids': range(i,10,2),
+ 'enabled': True,
+ 'expires': int(time.time())+60*60*24*30}
slices_list.append(slice)
users_list = []
def GetTestbedInfo():
return {'name': 'dummy', 'longitude': 123456, 'latitude': 654321, 'domain':'dummy-testbed.org'}
-def GetNodes(filter={}):
+def GetNodes(filter=None):
+ if filter is None: filter={}
global DB
result = []
result.extend(DB['nodes_list'])
result = FilterList(filter, result)
return result
-def GetSlices(filter={}):
+def GetSlices(filter=None):
+ if filter is None: filter={}
global DB
result = []
result.extend(DB['slices_list'])
return result
-def GetUsers(filter={}):
+def GetUsers(filter=None):
+ if filter is None: filter={}
global DB
result = []
result.extend(DB['users_list'])
return (slice, slivers)
- def get_nodes(self, options={}):
+ 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={}):
+ def get_slivers(self, urns, options=None):
+ if options is None: options={}
slice_names = set()
slice_ids = set()
node_ids = []
slivers.append(node)
return slivers
- def node_to_rspec_node(self, node, options={}):
+ 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'])
})
return rspec_node
- def get_slice_nodes(self, slice, options={}):
+ def get_slice_nodes(self, slice, options=None):
+ if options is None: options={}
nodes_dict = {}
filter = {}
if slice and slice.get('node_ids'):
nodes_dict[node['node_id']] = node
return nodes_dict
- def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+ 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']]
}
return geni_sliver
- def list_resources(self, version = None, options={}):
+ def list_resources(self, version = None, options=None):
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
return rspec.toxml()
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, 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, 'manifest')
def aggregate_version (self):
return {}
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
aggregate = DummyAggregate(self)
rspec = aggregate.list_resources(version=version, options=options)
return rspec
- def describe(self, urns, version, options={}):
+ def describe(self, urns, version, options=None):
+ if options is None: options={}
aggregate = DummyAggregate(self)
return aggregate.describe(urns, version=version, options=options)
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
aggregate = DummyAggregate(self)
desc = aggregate.describe(urns, version='GENI 3')
status = {'geni_urn': desc['geni_urn'],
return status
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
xrn = Xrn(urn)
aggregate = DummyAggregate(self)
slices = DummySlices(self)
return aggregate.describe([xrn.get_urn()], version=rspec.version)
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
# update users
slices = DummySlices(self)
aggregate = DummyAggregate(self)
rspec_version = version_manager.get_version(options['geni_rspec_version'])
return self.describe(urns, rspec_version, options=options)
- def delete(self, urns, options={}):
+ def delete(self, urns, options=None):
+ if options is None: options={}
# collect sliver ids so we can update sliver allocation states after
# we remove the slivers.
aggregate = DummyAggregate(self)
'geni_expires': datetime_to_string(utcparse(sliver['expires']))})
return geni_slivers
- def renew (self, urns, expiration_time, options={}):
+ def renew (self, urns, expiration_time, options=None):
+ if options is None: options={}
aggregate = DummyAggregate(self)
slivers = aggregate.get_slivers(urns)
if not slivers:
description = self.describe(urns, 'GENI 3', options)
return description['geni_slivers']
- def perform_operational_action (self, urns, action, options={}):
+ def perform_operational_action (self, urns, action, options=None):
+ if options is None: options={}
# Dummy doesn't support operational actions. Lets pretend like it
# supports start, but reject everything else.
action = action.lower()
geni_slivers = self.describe(urns, 'GENI 3', options)['geni_slivers']
return geni_slivers
- def shutdown (self, xrn, options={}):
+ def shutdown (self, xrn, options=None):
+ if options is None: options={}
xrn = DummyXrn(xrn=xrn, type='slice')
slicename = xrn.pl_slicename()
slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
return resulting_nodes
- def verify_slice(self, slice_hrn, slice_record, expiration, options={}):
+ def verify_slice(self, slice_hrn, slice_record, expiration, options=None):
+ if options is None: options={}
slicename = hrn_to_dummy_slicename(slice_hrn)
parts = slicename.split("_")
login_base = parts[0]
return slice
- def verify_users(self, slice_hrn, slice_record, users, options={}):
+ def verify_users(self, slice_hrn, slice_record, users, options=None):
+ if options is None: options={}
slice_name = hrn_to_dummy_slicename(slice_hrn)
users_by_email = {}
for user in users:
pass
- def verify_keys(self, old_users, new_users, options={}):
+ def verify_keys(self, old_users, new_users, options=None):
+ if options is None: options={}
# existing keys
existing_keys = []
for user in old_users:
return rspec_node
- def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+ def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = None):
"""Makes a geni sliver structure from all the nodes allocated
to slivers in the sliver_allocations dictionary. Returns the states
of the sliver.
.. seealso:: node_to_rspec_node
"""
+ 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']]
return rspec_node
- def get_leases(self, slice=None, options={}):
+ def get_leases(self, slice=None, options=None):
+ if options is None: options={}
filter={}
if slice:
#filter.update({'name':slice['slice_name']}) # JORDAN: this is = "upmc" !!!
FINAL RSPEC %s \r\n" % (rspec.toxml()))
return rspec.toxml()
- def get_slivers(self, urns, options={}):
+ def get_slivers(self, urns, options=None):
"""Get slivers of the given slice urns. Slivers contains slice, node and
user information.
"""
SLICE_KEY = 'slice_hrn' # slice_hrn
+ if options is None: options={}
slice_ids = set()
node_ids = []
for urn in urns:
slivers.append(node)
return slivers
- def list_resources(self, version = None, options={}):
+ def list_resources(self, version = None, options=None):
"""
Returns an advertisement Rspec of available resources at this
aggregate. This Rspec contains a resource listing along with their
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#ListResources
"""
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
rspec_version = version_manager._get_version(version.type,
return rspec.toxml()
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, version=None, options=None):
"""
Retrieve a manifest RSpec describing the resources contained by the
named entities, e.g. a single slice or a set of the slivers in a slice.
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe
.. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
"""
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
rspec_version = version_manager._get_version(
- def delete(self, slice_urns, options={}):
+ def delete(self, slice_urns, options=None):
"""
Deletes the lease associated with the slice hrn and the credentials
if the slice belongs to iotlab. Answer to DeleteSliver.
.. note:: creds are unused, and are not used either in the dummy driver
delete_sliver .
"""
+ if options is None: options={}
# collect sliver ids so we can update sliver allocation states after
# we remove the slivers.
aggregate = IotlabAggregate(self)
'geni_ad_rspec_versions': ad_rspec_versions}
# first 2 args are None in case of resource discovery
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
aggregate = IotlabAggregate(self)
rspec = aggregate.list_resources(version=version, options=options)
return rspec
- def describe(self, urns, version, options={}):
+ def describe(self, urns, version, options=None):
+ if options is None: options={}
aggregate = IotlabAggregate(self)
return aggregate.describe(urns, version=version, options=options)
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
aggregate = IotlabAggregate(self)
desc = aggregate.describe(urns, version='GENI 3')
status = {'geni_urn': desc['geni_urn'],
return status
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
xrn = Xrn(urn)
aggregate = IotlabAggregate(self)
}
return aggregate.describe([xrn.get_urn()], version=rspec.version, options=describe_options)
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
# update users
slices = IotlabSlices(self)
aggregate = IotlabAggregate(self)
return sfa_slice
- def verify_persons(self, slice_hrn, slice_record, users, options={}):
+ def verify_persons(self, slice_hrn, slice_record, users, options=None):
"""Ensures the users in users list exist and are enabled in LDAP. Adds
person if needed (AddPerson).
"""
+ if options is None: options={}
logger.debug("IOTLABSLICES \tverify_persons \tslice_hrn %s \
\t slice_record %s\r\n users %s \t "
% (slice_hrn, slice_record, users))
return added_persons
- def verify_keys(self, persons, users, peer, options={}):
+ def verify_keys(self, persons, users, peer, options=None):
"""
.. warning:: unused
"""
+ if options is None: options={}
# existing keys
key_ids = []
for person in persons:
'geni_ad_rspec_versions': ad_rspec_versions,
}
- def get_rspec_version_string(self, rspec_version, options={}):
+ def get_rspec_version_string(self, rspec_version, options=None):
+ if options is None: options={}
version_string = "rspec_%s" % (rspec_version)
#panos adding the info option to the caching key (can be improved)
return api.driver.renew(xrns, expiration_time, options)
- def PerformOperationalAction(self, api, xrns, creds, action, options={}):
+ def PerformOperationalAction(self, api, xrns, creds, action, options=None):
+ if options is None: options={}
call_id = options.get('call_id')
if Callids().already_handled(call_id): return True
return api.driver.perform_operational_action(xrns, action, options)
- def Shutdown(self, api, xrn, creds, options={}):
+ def Shutdown(self, api, xrn, creds, options=None):
+ if options is None: options={}
call_id = options.get('call_id')
if Callids().already_handled(call_id): return True
return api.driver.shutdown(xrn, options)
# answer to ListResources
# returns : advertisment rspec (xml string)
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
return "dummy Driver.list_resources needs to be redefined"
# the answer to Describe on a slice or a set of the slivers in a slice
# ...
# ]
#}
- def describe (self, urns, version, options={}):
+ def describe (self, urns, version, options=None):
+ if options is None: options={}
return "dummy Driver.describe needs to be redefined"
# the answer to Allocate on a given slicei or a set of the slivers in a slice
# returns: same struct as for describe.
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
return "dummy Driver.allocate needs to be redefined"
# the answer to Provision on a given slice or a set of the slivers in a slice
# returns: same struct as for describe.
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
return "dummy Driver.provision needs to be redefined"
# the answer to PerformOperationalAction on a given slice or a set of the slivers in a slice
# returns: struct containing "geni_slivers" list of the struct returned by describe.
- def perform_operational_action (self, urns, action, options={}):
+ def perform_operational_action (self, urns, action, options=None):
+ if options is None: options={}
return "dummy Driver.perform_operational_action needs to be redefined"
# the answer to Status on a given slice or a set of the slivers in a slice
# returns: struct containing "geni_urn" and "geni_slivers" list of the struct returned by describe.
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
return "dummy Driver.status needs to be redefined"
# the answer to Renew on a given slice or a set of the slivers in a slice
# returns: struct containing "geni_slivers" list of the struct returned by describe.
- def renew (self, urns, expiration_time, options={}):
+ def renew (self, urns, expiration_time, options=None):
+ if options is None: options={}
return "dummy Driver.renew needs to be redefined"
# the answer to Delete on a given slice
# returns: struct containing "geni_slivers" list of the struct returned by describe.
- def delete(self, urns, options={}):
+ def delete(self, urns, options=None):
+ if options is None: options={}
return "dummy Driver.delete needs to be redefined"
# the answer to Shutdown on a given slice
# returns: boolean
- def shutdown (self, xrn, options={}):
+ def shutdown (self, xrn, options=None):
+ if options is None: options={}
return False
# * write operations (register, update) need e.g.
# 'researcher' or 'pi' to be set - reg-* are just ignored
#
-# the 'normalize' helper functions below aim at ironing this out
+# the '_normalize_input' helper functions below aim at ironing this out
# however in order to break as few code as possible we essentially make sure that *both* fields are set
# upon entering the write methods (so again register and update) for legacy, as some driver code
# might depend on the presence of, say, 'researcher'
# and issue a warning if they were both set and different
# as we're overwriting some user data here
if driver_key in record:
- logger.warning ("normalize_input_researcher: incoming record has both values, using reg-researchers")
+ logger.warning ("normalize_input: incoming record has both values, using %s"%reg_key)
record[driver_key]=record[reg_key]
# we only have one key set, duplicate for the other one
elif driver_key in record:
- logger.warning ("normalize_input_researcher: you should use '%s' instead ot '%s'"%(reg_key,driver_key))
+ logger.warning ("normalize_input: you should use '%s' instead of '%s'"%(reg_key,driver_key))
record[reg_key]=record[driver_key]
def normalize_input_record (record):
_normalize_input (record, 'reg-researchers','researcher')
_normalize_input (record, 'reg-pis','pi')
+ _normalize_input (record, 'reg-keys','keys')
+ # xxx the keys thing could use a little bit more attention:
+ # some parts of the code are using 'keys' while they should use 'reg-keys'
+ # but I run out of time for now
+ if 'reg-keys' in record: record['keys']=record['reg-keys']
return record
class RegistryManager:
if hrn != api.hrn])
xrn=Xrn(api.hrn,type='authority')
return version_core({'interface':'registry',
- 'sfa': 2,
- 'geni_api': 2,
+ 'sfa': 3,
'hrn':xrn.get_hrn(),
'urn':xrn.get_urn(),
'peers':peers})
return records
- def List (self, api, xrn, origin_hrn=None, options={}):
+ def List (self, api, xrn, origin_hrn=None, options=None):
+ if options is None: options={}
dbsession=api.dbsession()
# load all know registry names into a prefix tree and attempt to find
# the longest matching prefix
if not record.gid:
uuid = create_uuid()
pkey = Keypair(create=True)
- if getattr(record,'keys',None):
- pub_key=record.keys
+ pub_key=getattr(record,'reg-keys',None)
+ if pub_key is not None:
# use only first key in record
- if isinstance(record.keys, types.ListType):
- pub_key = record.keys[0]
+ if pub_key and isinstance(pub_key, types.ListType): pub_key = pub_key[0]
pkey = convert_public_key(pub_key)
gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
elif isinstance (record, RegUser):
# create RegKey objects for incoming keys
- if hasattr(record,'keys'):
- logger.debug ("creating %d keys for user %s"%(len(record.keys),record.hrn))
- record.reg_keys = [ RegKey (key) for key in record.keys ]
+ if hasattr(record,'reg-keys'):
+ keys=getattr(record,'reg-keys')
+ # some people send the key as a string instead of a list of strings
+ if isinstance(keys,types.StringTypes): keys=[keys]
+ logger.debug ("creating %d keys for user %s"%(len(keys),record.hrn))
+ record.reg_keys = [ RegKey (key) for key in keys ]
# update testbed-specific data if needed
pointer = api.driver.register (record.__dict__, hrn, pub_key)
multiclient.get_results()
return 1
- def Shutdown(self, api, xrn, creds, options={}):
+ def Shutdown(self, api, xrn, creds, options=None):
+ if options is None: options={}
xrn = Xrn(xrn)
# get the callers hrn
valid_cred = api.auth.checkCredentials(creds, 'stopslice', xrn.hrn)[0]
# the slivers should expire.
expiration = datetime_to_string(the_credential.expiration)
+ self.api.logger.debug("Allocate, received expiration from credential: %s"%expiration)
+
# make sure request is not empty
slivers = RSpec(rspec).version.get_nodes_with_slivers()
if not slivers:
returns = Parameter(dict, "Version information")
# API v2 specifies options is optional, so..
- def call(self, options={}):
+ def call(self, options=None):
+ if options is None: options={}
self.api.logger.info("interface: %s\tmethod-name: %s" % (self.api.interface, self.name))
return self.api.manager.GetVersion(self.api, options)
# xxx used to be [SfaRecord]
returns = [Parameter(dict, "registry record")]
- def call(self, xrn, creds, options={}):
+ def call(self, xrn, creds, options=None):
+ if options is None: options={}
hrn, type = urn_to_hrn(xrn)
valid_creds = self.api.auth.checkCredentials(creds, 'list')
# xxx used to be [SfaRecord]
returns = [Parameter(dict, "registry record")]
- def call(self, xrns, creds, options={}):
+ def call(self, xrns, creds, options=None):
+ if options is None: options={}
# use details=False by default, only when explicitly specified do we want
# to mess with the testbed details
if 'details' in options: details=options['details']
- def get_nodes(self, slice_xrn, slice=None,slivers={}, options={}):
+ def get_nodes(self, slice_xrn, slice=None,slivers=None, options=None):
+ if slivers is None: slivers={}
+ if options is None: options={}
# if we are dealing with a slice that has no node just return
# and empty list
if slice_xrn:
rspec_nodes.append(rspec_node)
return rspec_nodes
- def get_leases_and_channels(self, slice=None, slice_xrn=None, options={}):
-
+ def get_leases_and_channels(self, slice=None, slice_xrn=None, options=None):
+
+ if options is None: options={}
slices = self.driver.shell.getSlices({}, [])
nodes = self.driver.shell.getNodes({}, [])
leases = self.driver.shell.getReservedNodes({}, [])
return (rspec_leases, rspec_channels)
- def get_channels(self, slice=None, options={}):
-
+ def get_channels(self, slice=None, options=None):
+ if options is None: options={}
+
all_channels = self.driver.shell.getChannels({}, [])
channels = []
if slice:
- def get_rspec(self, slice_xrn=None, version = None, options={}):
+ def get_rspec(self, slice_xrn=None, version = None, options=None):
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
- def verify_slice(self, slice_hrn, slice_record, sfa_peer, options={}):
+ def verify_slice(self, slice_hrn, slice_record, sfa_peer, options=None):
+ if options is None: options={}
slicename = hrn_to_nitos_slicename(slice_hrn)
slices = self.driver.shell.getSlices({}, [])
slices = self.driver.filter_nitos_results(slices, {'slice_name': slicename})
return slice
- def verify_users(self, slice_hrn, slice_record, users, sfa_peer, options={}):
+ def verify_users(self, slice_hrn, slice_record, users, sfa_peer, options=None):
+ if options is None: options={}
# get slice info
slicename = hrn_to_nitos_slicename(slice_hrn)
slices = self.driver.shell.getSlices({}, [])
return added_users
- def verify_keys(self, persons, users, options={}):
+ def verify_keys(self, persons, users, options=None):
+ if options is None: options={}
# existing keys
key_ids = []
for person in persons:
class Image:
- def __init__(self, image={}):
+ def __init__(self, image=None):
+ if image is None: image={}
self.id = None
self.container_format = None
self.kernel_id = None
return {}
# first 2 args are None in case of resource discovery
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
aggregate = OSAggregate(self)
rspec = aggregate.list_resources(version=version, options=options)
return rspec
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, version=None, options=None):
+ if options is None: options={}
aggregate = OSAggregate(self)
return aggregate.describe(urns, version=version, options=options)
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
aggregate = OSAggregate(self)
desc = aggregate.describe(urns)
status = {'geni_urn': desc['geni_urn'],
'geni_slivers': desc['geni_slivers']}
return status
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
xrn = Xrn(urn)
aggregate = OSAggregate(self)
return aggregate.describe(urns=[urn], version=rspec.version)
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
# update sliver allocation states and set them to geni_provisioned
aggregate = OSAggregate(self)
instances = aggregate.get_instances(urns)
rspec_version = version_manager.get_version(options['geni_rspec_version'])
return self.describe(urns, rspec_version, options=options)
- def delete (self, urns, options={}):
+ def delete (self, urns, options=None):
+ if options is None: options={}
# collect sliver ids so we can update sliver allocation states after
# we remove the slivers.
aggregate = OSAggregate(self)
'geni_expires': None})
return geni_slivers
- def renew (self, urns, expiration_time, options={}):
+ def renew (self, urns, expiration_time, options=None):
+ if options is None: options={}
description = self.describe(urns, None, options)
return description['geni_slivers']
- def perform_operational_action (self, urns, action, options={}):
+ def perform_operational_action (self, urns, action, options=None):
+ if options is None: options={}
aggregate = OSAggregate(self)
action = action.lower()
if action == 'geni_start':
geni_slivers = self.describe(urns, None, options)['geni_slivers']
return geni_slivers
- def shutdown(self, xrn, options={}):
+ def shutdown(self, xrn, options=None):
+ if options is None: options={}
xrn = OSXrn(xrn=xrn, type='slice')
tenant_name = xrn.get_tenant_name()
name = xrn.get_slicename()
from collections import defaultdict
from nova.exception import ImageNotFound
from nova.api.ec2.cloud import CloudController
-from sfa.util.faults import SfaAPIError, SliverDoesNotExist
+from sfa.util.faults import SliverDoesNotExist
from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
from sfa.rspecs.rspec import RSpec
from sfa.rspecs.elements.hardware_type import HardwareType
zones = [zone.name for zone in zones]
return zones
- def list_resources(self, version=None, options={}):
+ 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.version.add_nodes(nodes)
return rspec.toxml()
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, version=None, options=None):
+ if options is None: options={}
# update nova connection
tenant_name = OSXrn(xrn=urns[0], type='slice').get_tenant_name()
self.driver.shell.nova_manager.connect(tenant=tenant_name)
'storage': str(instance.disk)})
return sliver
- def instance_to_geni_sliver(self, instance, sliver_allocations = {}):
+ def instance_to_geni_sliver(self, instance, sliver_allocations=None):
+ if sliver_allocations is None: sliver_allocations={}
sliver_hrn = '%s.%s' % (self.driver.hrn, instance.id)
sliver_id = Xrn(sliver_hrn, type='sliver').urn
return key_name
- def create_security_group(self, slicename, fw_rules=[]):
+ def create_security_group(self, slicename, fw_rules=None):
+ if fw_rules is None: fw_rules=[]
# use default group by default
group_name = 'default'
if isinstance(fw_rules, list) and fw_rules:
def __init__(self, driver):
self.driver = driver
- def get_nodes(self, options={}):
+ def get_nodes(self, options=None):
+ if options is None: options={}
filter = {'peer_id': None}
geni_available = options.get('geni_available')
if geni_available == True:
return nodes
- def get_sites(self, filter={}):
+ def get_sites(self, filter=None):
+ if filter is None: filter={}
sites = {}
for site in self.driver.shell.GetSites(filter):
sites[site['site_id']] = site
return sites
- def get_interfaces(self, filter={}):
+ def get_interfaces(self, filter=None):
+ if filter is None: filter={}
interfaces = {}
for interface in self.driver.shell.GetInterfaces(filter):
iface = Interface()
return links
- def get_node_tags(self, filter={}):
+ def get_node_tags(self, filter=None):
+ if filter is None: filter={}
node_tags = {}
for node_tag in self.driver.shell.GetNodeTags(filter):
node_tags[node_tag['node_tag_id']] = node_tag
return node_tags
- def get_pl_initscripts(self, filter={}):
+ def get_pl_initscripts(self, filter=None):
+ if filter is None: filter={}
pl_initscripts = {}
filter.update({'enabled': True})
for initscript in self.driver.shell.GetInitScripts(filter):
pl_initscripts[initscript['initscript_id']] = initscript
return pl_initscripts
- def get_slivers(self, urns, options={}):
+ def get_slivers(self, urns, options=None):
+ if options is None: options={}
names = set()
slice_ids = set()
node_ids = []
slivers.append(node)
return slivers
- def node_to_rspec_node(self, node, sites, interfaces, node_tags, pl_initscripts=[], grain=None, options={}):
+ def node_to_rspec_node(self, node, sites, interfaces, node_tags, pl_initscripts=None, grain=None, options=None):
+ if pl_initscripts is None: pl_initscripts=[]
+ if options is None: options={}
rspec_node = NodeElement()
# xxx how to retrieve site['login_base']
site=sites[node['site_id']]
tags_dict[tag['node_id']] = tag
return tags_dict
- def get_slice_nodes(self, slice, options={}):
+ def get_slice_nodes(self, slice, options=None):
+ if options is None: options={}
nodes_dict = {}
filter = {'peer_id': None}
tags_filter = {}
nodes_dict[node['node_id']] = node
return nodes_dict
- def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+ 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']]
}
return geni_sliver
- def get_leases(self, slice=None, options={}):
+ def get_leases(self, slice=None, options=None):
+ if options is None: options={}
now = int(time.time())
filter={}
return rspec_leases
- def list_resources(self, version = None, options={}):
+ def list_resources(self, version = None, options=None):
+ if options is None: options={}
version_manager = VersionManager()
version = version_manager.get_version(version)
return rspec.toxml()
- def describe(self, urns, version=None, options={}):
+ def describe(self, urns, 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, 'manifest')
return {}
# first 2 args are None in case of resource discovery
- def list_resources (self, version=None, options={}):
+ def list_resources (self, version=None, options=None):
+ if options is None: options={}
aggregate = PlAggregate(self)
rspec = aggregate.list_resources(version=version, options=options)
return rspec
- def describe(self, urns, version, options={}):
+ def describe(self, urns, version, options=None):
+ if options is None: options={}
aggregate = PlAggregate(self)
return aggregate.describe(urns, version=version, options=options)
- def status (self, urns, options={}):
+ def status (self, urns, options=None):
+ if options is None: options={}
aggregate = PlAggregate(self)
desc = aggregate.describe(urns, version='GENI 3')
status = {'geni_urn': desc['geni_urn'],
'geni_slivers': desc['geni_slivers']}
return status
- def allocate (self, urn, rspec_string, expiration, options={}):
+ def allocate (self, urn, rspec_string, expiration, options=None):
+ if options is None: options={}
xrn = Xrn(urn)
aggregate = PlAggregate(self)
slices = PlSlices(self)
return aggregate.describe([xrn.get_urn()], version=rspec.version)
- def provision(self, urns, options={}):
+ def provision(self, urns, options=None):
+ if options is None: options={}
# update users
slices = PlSlices(self)
aggregate = PlAggregate(self)
rspec_version = version_manager.get_version(options['geni_rspec_version'])
return self.describe(urns, rspec_version, options=options)
- def delete(self, urns, options={}):
+ def delete(self, urns, options=None):
+ if options is None: options={}
# collect sliver ids so we can update sliver allocation states after
# we remove the slivers.
aggregate = PlAggregate(self)
'geni_expires': datetime_to_string(utcparse(sliver['expires']))})
return geni_slivers
- def renew (self, urns, expiration_time, options={}):
+ def renew (self, urns, expiration_time, options=None):
+ if options is None: options={}
aggregate = PlAggregate(self)
slivers = aggregate.get_slivers(urns)
if not slivers:
return description['geni_slivers']
- def perform_operational_action (self, urns, action, options={}):
+ def perform_operational_action (self, urns, action, options=None):
+ if options is None: options={}
# MyPLC doesn't support operational actions. Lets pretend like it
# supports start, but reject everything else.
action = action.lower()
return geni_slivers
# set the 'enabled' tag to 0
- def shutdown (self, xrn, options={}):
+ def shutdown (self, xrn, options=None):
+ if options is None: options={}
hrn, _ = urn_to_hrn(xrn)
top_auth_hrn = top_auth(hrn)
site_hrn = '.'.join(hrn.split('.')[:-1])
- def verify_site(self, slice_xrn, slice_record={}, sfa_peer=None, options={}):
+ def verify_site(self, slice_xrn, slice_record=None, sfa_peer=None, options=None):
+ if slice_record is None: slice_record={}
+ if options is None: options={}
(slice_hrn, type) = urn_to_hrn(slice_xrn)
top_auth_hrn = top_auth(slice_hrn)
site_hrn = '.'.join(slice_hrn.split('.')[:-1])
return site
- def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options={}):
+ def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options=None):
+ if options is None: options={}
top_auth_hrn = top_auth(slice_hrn)
site_hrn = '.'.join(slice_hrn.split('.')[:-1])
slice_part = slice_hrn.split('.')[-1]
return self.driver.shell.GetSlices(int(slice['slice_id']))[0]
- def verify_persons(self, slice_hrn, slice_record, users, sfa_peer, options={}):
+ def verify_persons(self, slice_hrn, slice_record, users, sfa_peer, options=None):
+ if options is None: options={}
top_auth_hrn = top_auth(slice_hrn)
site_hrn = '.'.join(slice_hrn.split('.')[:-1])
slice_part = slice_hrn.split('.')[-1]
return persons_to_add
- def verify_keys(self, persons_to_verify_keys, options={}):
+ def verify_keys(self, persons_to_verify_keys, options=None):
+ if options is None: options={}
# we only add keys that comes from sfa to persons in PL
for person_id in persons_to_verify_keys:
person_sfa_keys = persons_to_verify_keys[person_id].get('keys', [])
self.driver.shell.AddPersonKey(int(person_id), key)
- def verify_slice_attributes(self, slice, requested_slice_attributes, options={}, admin=False):
+ def verify_slice_attributes(self, slice, requested_slice_attributes, options=None, admin=False):
+ if options is None: options={}
append = options.get('append', True)
# get list of attributes users ar able to manage
filter = {'category': '*slice*'}
fields = {}
- def __init__(self, fields={}, element=None, keys=None):
+ def __init__(self, fields=None, element=None, keys=None):
+ if fields is None: fields={}
self.element = element
dict.__init__(self, dict.fromkeys(self.fields))
if not keys:
@staticmethod
- def get_leases(xml, filter={}):
+ def get_leases(xml, filter=None):
+ if filter is None: filter={}
xpath = '//lease%s | //default:lease%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
lease_elems = xml.xpath(xpath)
return Iotlabv1Lease.get_lease_objs(lease_elems)
return node_elems
@staticmethod
- def get_nodes(xml, filter={}):
+ def get_nodes(xml, filter=None):
+ if filter is None: filter={}
xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), \
XpathFilter.xpath(filter))
node_elems = xml.xpath(xpath)
return Iotlabv1Node.get_node_objs(node_elems)
@staticmethod
- def get_nodes_with_slivers(xml, sliver_filter={}):
+ def get_nodes_with_slivers(xml, sliver_filter=None):
+ if sliver_filter is None: sliver_filter={}
xpath = '//node[count(sliver)>0] | \
//default:node[count(default:sliver) > 0]'
for (key, value) in attrib_dict.items():
attrib_elem.set(key, value)
@staticmethod
- def get_slivers(xml, filter={}):
+ def get_slivers(xml, filter=None):
+ if filter is None: filter={}
xpath = './default:sliver | ./sliver'
sliver_elems = xml.xpath(xpath)
return slivers
@staticmethod
- def get_sliver_attributes(xml, filter={}):
- return []
\ No newline at end of file
+ def get_sliver_attributes(xml, filter=None):
+ if filter is None: filter={}
+ return []
@staticmethod
- def get_channels(xml, filter={}):
+ def get_channels(xml, filter=None):
+ if filter is None: filter={}
xpath = '//channel%s | //default:channel%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
channel_elems = xml.xpath(xpath)
return NITOSv1Channel.get_channel_objs(channel_elems)
@staticmethod
- def get_leases(xml, filter={}):
+ def get_leases(xml, filter=None):
+ if filter is None: filter={}
xpath = '//lease%s | //default:lease%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
lease_elems = xml.xpath(xpath)
return NITOSv1Lease.get_lease_objs(lease_elems)
node.element.remove(sliver.element)
@staticmethod
- def get_nodes(xml, filter={}):
+ def get_nodes(xml, filter=None):
+ if filter is None: filter={}
xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
node_elems = xml.xpath(xpath)
return NITOSv1Node.get_node_objs(node_elems)
pl_tag_elem.set_text(value)
@staticmethod
- def get_pl_tags(xml, ignore=[]):
+ def get_pl_tags(xml, ignore=None):
+ if ignore is None: ignore=[]
pl_tags = []
for elem in xml.iterchildren():
if elem.tag not in ignore:
return attribs
@staticmethod
- def get_slivers(xml, filter={}):
+ def get_slivers(xml, filter=None):
+ if filter is None: filter={}
xpath = './default:sliver | ./sliver'
sliver_elems = xml.xpath(xpath)
slivers = []
return attribs
@staticmethod
- def get_ports(xml, filter={}):
+ def get_ports(xml, filter=None):
+ if filter is None: filter={}
xpath = './openflow:port | ./port'
port_elems = xml.xpath(xpath)
ports = []
class Ofeliav1Datapath:
@staticmethod
- def get_datapaths(xml, filter={}):
+ def get_datapaths(xml, filter=None):
+ if filter is None: filter={}
#xpath = '//datapath%s | //default:datapath%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
xpath = '//datapath%s | //openflow:datapath%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
datapath_elems = xml.xpath(xpath)
# node.element.remove(sliver.element)
#
# @staticmethod
-# def get_nodes(xml, filter={}):
+# def get_nodes(xml, filter=None):
+# if filter is None: filter={}
# xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
# node_elems = xml.xpath(xpath)
# return SFAv1Node.get_node_objs(node_elems)
class Ofeliav1Link:
@staticmethod
- def get_links(xml, filter={}):
+ def get_links(xml, filter=None):
+ if filter is None: filter={}
xpath = '//link%s | //openflow:link%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
link_elems = xml.xpath(xpath)
return Ofeliav1Link.get_link_objs(link_elems)
xml.add_instance('disk_image', image, DiskImage.fields)
@staticmethod
- def get_images(xml, filter={}):
+ def get_images(xml, filter=None):
+ if filter is None: filter={}
xpath = './default:disk_image | ./disk_image'
image_elems = xml.xpath(xpath)
images = []
@staticmethod
- def get_leases(xml, filter={}):
+ def get_leases(xml, filter=None):
+ if filter is None: filter={}
xpath = '//lease%s | //default:lease%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
lease_elems = xml.xpath(xpath)
return PGv2Lease.get_lease_objs(lease_elems)
@staticmethod
- def get_nodes(xml, filter={}):
+ def get_nodes(xml, filter=None):
+ if filter is None: filter={}
xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
node_elems = xml.xpath(xpath)
return PGv2Node.get_node_objs(node_elems)
@staticmethod
- def get_nodes_with_slivers(xml, filter={}):
+ def get_nodes_with_slivers(xml, filter=None):
+ if filter is None: filter={}
xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]'
node_elems = xml.xpath(xpath)
return PGv2Node.get_node_objs(node_elems)
for (key, value) in attrib_dict.items():
attrib_elem.set(key, value)
@staticmethod
- def get_slivers(xml, filter={}):
+ def get_slivers(xml, filter=None):
+ if filter is None: filter={}
xpath = './default:sliver_type | ./sliver_type'
sliver_elems = xml.xpath(xpath)
slivers = []
return slivers
@staticmethod
- def get_sliver_attributes(xml, filter={}):
+ def get_sliver_attributes(xml, filter=None):
+ if filter is None: filter={}
return []
@staticmethod
- def get_leases(xml, filter={}):
+ def get_leases(xml, filter=None):
+ if filter is None: filter={}
xpath = '//lease%s | //default:lease%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
lease_elems = xml.xpath(xpath)
return SFAv1Lease.get_lease_objs(lease_elems)
node.element.remove(sliver.element)
@staticmethod
- def get_nodes(xml, filter={}):
+ def get_nodes(xml, filter=None):
+ if filter is None: filter={}
xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
node_elems = xml.xpath(xpath)
return SFAv1Node.get_node_objs(node_elems)
pl_tag_elem.set_text(value)
@staticmethod
- def get_pl_tags(xml, ignore=[]):
+ def get_pl_tags(xml, ignore=None):
+ if ignore is None: ignore=[]
pl_tags = []
for elem in xml.iterchildren():
if elem.tag not in ignore:
return attribs
@staticmethod
- def get_slivers(xml, filter={}):
+ def get_slivers(xml, filter=None):
+ if filter is None: filter={}
xpath = './default:sliver | ./sliver'
sliver_elems = xml.xpath(xpath)
slivers = []
class RSpec:
- def __init__(self, rspec="", version=None, user_options={}):
+ def __init__(self, rspec="", version=None, user_options=None, ttl=60):
+ if user_options is None: user_options={}
self.header = '<?xml version="1.0"?>\n'
self.template = """<RSpec></RSpec>"""
self.version = None
self.xml = XML()
self.version_manager = VersionManager()
self.user_options = user_options
+ self.ttl = ttl
self.elements = {}
if rspec:
if version:
else:
raise InvalidRSpec("No RSpec or version specified. Must specify a valid rspec string or a valid version")
- def create(self, version=None):
+ def create(self, version=None, ttl=60):
"""
Create root element
+ ttl: time to live in minutes, this will determine the expires tag of the RSpec
"""
self.version = self.version_manager.get_version(version)
self.namespaces = self.version.namespaces
self.parse_xml(self.version.template, self.version)
now = datetime.utcnow()
generated_ts = now.strftime(SFATIME_FORMAT)
- expires_ts = (now + timedelta(hours=1)).strftime(SFATIME_FORMAT)
+ expires_ts = (now + timedelta(minutes=self.ttl)).strftime(SFATIME_FORMAT)
self.xml.set('expires', expires_ts)
self.xml.set('generated', generated_ts)
raise InvalidRSpecElement(element_type, extra=msg)
return self.elements[element_type]
- def get(self, element_type, filter={}, depth=0):
+ def get(self, element_type, filter=None, depth=0):
+ if filter is None: filter={}
elements = self.get_elements(element_type, filter)
elements = [self.xml.get_element_attributes(elem, depth=depth) for elem in elements]
return elements
- def get_elements(self, element_type, filter={}):
+ def get_elements(self, element_type, filter=None):
"""
search for a registered element
"""
+ if filter is None: filter={}
if element_type not in self.elements:
msg = "Unable to search for element %s in rspec, expath expression not found." % \
element_type
def add_default_sliver_attribute(self, name, value, network=None):
pass
- def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
+ def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
+ if attributes is None: attributes=[]
# all nodes hould already be present in the rspec. Remove all
# nodes that done have slivers
print>>sys.stderr, "\r\n \r\n \r\n \t\t\t Iotlabv1.PY add_slivers ----->get_node "
# Slivers
- def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
+ def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
+ if attributes is None: attributes=[]
# add slice name to network tag
network_tags = self.xml.xpath('//network')
if network_tags:
# Slivers
- def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
+ def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
+ if attributes is None: attributes=[]
# add slice name to network tag
network_tags = self.xml.xpath('//network')
if network_tags:
def add_default_sliver_attribute(self, name, value, network=None):
pass
- def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
+ def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
+ if attributes is None: attributes=[]
# all nodes hould already be present in the rspec. Remove all
# nodes that done have slivers
for hostname in hostnames:
# Slivers
- def add_slivers(self, hostnames, attributes=[], sliver_urn=None, append=False):
+ def add_slivers(self, hostnames, attributes=None, sliver_urn=None, append=False):
+ if attributes is None: attributes=[]
# add slice name to network tag
network_tags = self.xml.xpath('//network')
if network_tags:
##############################
# create a record of the right type from either a dict or an xml string
-def make_record (dict={}, xml=""):
+def make_record (dict=None, xml=""):
+ if dict is None: dict={}
if dict: return make_record_dict (dict)
elif xml: return make_record_xml (xml)
else: raise Exception("make_record has no input")
# it may be important to exclude relationships, which fortunately
#
- def todict (self, exclude_types=[]):
+ def todict (self, exclude_types=None):
+ if exclude_types is None: exclude_types=[]
d=self.__dict__
def exclude (k,v):
if k.startswith('_'): return True
# IN THE WORK.
#----------------------------------------------------------------------
-from sfa.trust.credential import Credential, append_sub
+from sfa.trust.credential import Credential, append_sub, DEFAULT_CREDENTIAL_LIFETIME
from sfa.util.sfalogging import logger
+from sfa.util.sfatime import SFATIME_FORMAT
from StringIO import StringIO
from xml.dom.minidom import Document, parseString
filename=self.get_filename()
if filename: result += "Filename %s\n"%filename
if self.expiration:
- result += "\texpiration: %s \n" % self.expiration.isoformat()
+ result += "\texpiration: %s \n" % self.expiration.strftime(SFATIME_FORMAT)
result += "\tHead: %s\n" % self.get_head()
for tail in self.get_tails():
if self.expiration.tzinfo is not None and self.expiration.tzinfo.utcoffset(self.expiration) is not None:
# TZ aware. Make sure it is UTC
self.expiration = self.expiration.astimezone(tz.tzutc())
- append_sub(doc, cred, "expires", self.expiration.strftime('%Y-%m-%dT%H:%M:%SZ')) # RFC3339
+ append_sub(doc, cred, "expires", self.expiration.strftime(SFATIME_FORMAT)) # RFC3339
abac = doc.createElement("abac")
rt0 = doc.createElement("rt0")
# SfaAPI authentication
#
import sys
+from types import StringTypes
from sfa.util.faults import InsufficientRights, MissingCallerGID, MissingTrustedRoots, PermissionError, \
BadRequestHash, ConnectionKeyGIDMismatch, SfaPermissionDenied, CredentialNotVerifiable, Forbidden, \
speaking_for_xrn=None):
if xrns is None: xrns=[]
def log_invalid_cred(cred):
- cred_obj=Credential(string=cred)
- logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
- error = sys.exc_info()[:2]
+ if not isinstance (cred, StringTypes):
+ logger.info("cannot validate credential %s - expecting a string"%cred)
+ error="checkCredentials: expected a string, received %s"%(type(cred))
+ else:
+ cred_obj=Credential(string=cred)
+ logger.info("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
+ error = sys.exc_info()[:2]
return error
# if xrns are specified they cannot be None or empty string
from sfa.util.faults import CredentialNotVerifiable, ChildRightsNotSubsetOfParent
from sfa.util.sfalogging import logger
-from sfa.util.sfatime import utcparse
-from sfa.trust.credential_legacy import CredentialLegacy
+from sfa.util.sfatime import utcparse, SFATIME_FORMAT
from sfa.trust.rights import Right, Rights, determine_rights
from sfa.trust.gid import GID
from sfa.util.xrn import urn_to_hrn, hrn_authfor_hrn
-# 2 weeks, in seconds
-DEFAULT_CREDENTIAL_LIFETIME = 86400 * 31
+# 31 days, in seconds
+DEFAULT_CREDENTIAL_LIFETIME = 86400 * 28
# TODO:
# A credential provides a caller gid with privileges to an object gid.
# A signed credential is signed by the object's authority.
#
-# Credentials are encoded in one of two ways. The legacy style places
-# it in the subjectAltName of an X509 certificate. The new credentials
-# are placed in signed XML.
+# Credentials are encoded in one of two ways.
+# The legacy style (now unsupported) places it in the subjectAltName of an X509 certificate.
+# The new credentials are placed in signed XML.
#
# WARNING:
# In general, a signed credential obtained externally should
self.signature = None
self.xml = None
self.refid = None
- self.legacy = None
self.type = None
self.version = None
self.version = cred['geni_version']
- # Check if this is a legacy credential, translate it if so
if string or filename:
if string:
str = string
elif filename:
str = file(filename).read()
- if str.strip().startswith("-----"):
- self.legacy = CredentialLegacy(False,string=str)
- self.translate_legacy(str)
+ # if this is a legacy credential, write error and bail out
+ if isinstance (str, StringTypes) and str.strip().startswith("-----"):
+ logger.error("Legacy credentials not supported any more - giving up with %s..."%str[:10])
+ return
else:
self.xml = str
self.decode()
self.signature = sig
- ##
- # Translate a legacy credential into a new one
- #
- # @param String of the legacy credential
-
- def translate_legacy(self, str):
- legacy = CredentialLegacy(False,string=str)
- self.gidCaller = legacy.get_gid_caller()
- self.gidObject = legacy.get_gid_object()
- lifetime = legacy.get_lifetime()
- if not lifetime:
- self.set_expiration(datetime.datetime.utcnow() + datetime.timedelta(seconds=DEFAULT_CREDENTIAL_LIFETIME))
- else:
- self.set_expiration(int(lifetime))
- self.lifeTime = legacy.get_lifetime()
- self.set_privileges(legacy.get_privileges())
- self.get_privileges().delegate_all_privileges(legacy.get_delegate())
-
##
# Need the issuer's private key and name
# @param key Keypair object containing the private key of the issuer
# Expiration: an absolute UTC time of expiration (as either an int or string or datetime)
#
def set_expiration(self, expiration):
- if isinstance(expiration, (int, float)):
- self.expiration = datetime.datetime.fromtimestamp(expiration)
- elif isinstance (expiration, datetime.datetime):
- self.expiration = expiration
- elif isinstance (expiration, StringTypes):
- self.expiration = utcparse (expiration)
+ expiration_datetime = utcparse (expiration)
+ if expiration_datetime is not None:
+ self.expiration = expiration_datetime
else:
- logger.error ("unexpected input type in Credential.set_expiration")
-
+ logger.error ("unexpected input %s in Credential.set_expiration"%expiration)
##
# get the lifetime of the credential (always in datetime format)
# at this point self.expiration is normalized as a datetime - DON'T call utcparse again
return self.expiration
- ##
- # For legacy sake
- def get_lifetime(self):
- return self.get_expiration()
-
##
# set the privileges
#
append_sub(doc, cred, "target_urn", self.gidObject.get_urn())
append_sub(doc, cred, "uuid", "")
if not self.expiration:
+ logger.debug("Creating credential valid for %s s"%DEFAULT_CREDENTIAL_LIFETIME)
self.set_expiration(datetime.datetime.utcnow() + datetime.timedelta(seconds=DEFAULT_CREDENTIAL_LIFETIME))
self.expiration = self.expiration.replace(microsecond=0)
- append_sub(doc, cred, "expires", self.expiration.isoformat())
+ append_sub(doc, cred, "expires", self.expiration.strftime(SFATIME_FORMAT))
privileges = doc.createElement("privileges")
cred.appendChild(privileges)
self.xml = signed
- # This is no longer a legacy credential
- if self.legacy:
- self.legacy = None
-
# Update signatures
self.decode()
self.decode()
# validate against RelaxNG schema
- if HAVELXML and not self.legacy:
+ if HAVELXML:
if schema and os.path.exists(schema):
tree = etree.parse(StringIO(self.xml))
schema_doc = etree.parse(schema)
logger.error("Failed to load trusted cert from %s: %r"%( f, exc))
trusted_certs = ok_trusted_certs
- # Use legacy verification if this is a legacy credential
- if self.legacy:
- self.legacy.verify_chain(trusted_cert_objects)
- if self.legacy.client_gid:
- self.legacy.client_gid.verify_chain(trusted_cert_objects)
- if self.legacy.object_gid:
- self.legacy.object_gid.verify_chain(trusted_cert_objects)
- return True
-
# make sure it is not expired
if self.get_expiration() < datetime.datetime.utcnow():
- raise CredentialNotVerifiable("Credential %s expired at %s" % (self.get_summary_tostring(), self.expiration.isoformat()))
+ raise CredentialNotVerifiable("Credential %s expired at %s" % (self.get_summary_tostring(), self.expiration.strftime(SFATIME_FORMAT)))
# Verify the signatures
filename = self.save_to_random_tmp_file()
self.get_signature().get_issuer_gid().dump(8, dump_parents)
if self.expiration:
- print " expiration:", self.expiration.isoformat()
+ print " expiration:", self.expiration.strftime(SFATIME_FORMAT)
gidObject = self.get_gid_object()
if gidObject:
+++ /dev/null
-#----------------------------------------------------------------------
-# Copyright (c) 2008 Board of Trustees, Princeton University
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and/or hardware specification (the "Work") to
-# deal in the Work without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Work, and to permit persons to whom the Work
-# is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Work.
-#
-# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
-# IN THE WORK.
-#----------------------------------------------------------------------
-##
-# Implements SFA Credentials
-#
-# Credentials are layered on top of certificates, and are essentially a
-# certificate that stores a tuple of parameters.
-##
-
-
-import xmlrpclib
-
-from sfa.util.faults import MissingDelegateBit, ChildRightsNotSubsetOfParent
-from sfa.trust.certificate import Certificate
-from sfa.trust.gid import GID
-
-##
-# Credential is a tuple:
-# (GIDCaller, GIDObject, LifeTime, Privileges, Delegate)
-#
-# These fields are encoded using xmlrpc into the subjectAltName field of the
-# x509 certificate. Note: Call encode() once the fields have been filled in
-# to perform this encoding.
-
-class CredentialLegacy(Certificate):
- gidCaller = None
- gidObject = None
- lifeTime = None
- privileges = None
- delegate = False
-
- ##
- # Create a Credential object
- #
- # @param create If true, create a blank x509 certificate
- # @param subject If subject!=None, create an x509 cert with the subject name
- # @param string If string!=None, load the credential from the string
- # @param filename If filename!=None, load the credential from the file
-
- def __init__(self, create=False, subject=None, string=None, filename=None):
- Certificate.__init__(self, create, subject, string, filename)
-
- ##
- # set the GID of the caller
- #
- # @param gid GID object of the caller
-
- def set_gid_caller(self, gid):
- self.gidCaller = gid
- # gid origin caller is the caller's gid by default
- self.gidOriginCaller = gid
-
- ##
- # get the GID of the object
-
- def get_gid_caller(self):
- if not self.gidCaller:
- self.decode()
- return self.gidCaller
-
- ##
- # set the GID of the object
- #
- # @param gid GID object of the object
-
- def set_gid_object(self, gid):
- self.gidObject = gid
-
- ##
- # get the GID of the object
-
- def get_gid_object(self):
- if not self.gidObject:
- self.decode()
- return self.gidObject
-
- ##
- # set the lifetime of this credential
- #
- # @param lifetime lifetime of credential
-
- def set_lifetime(self, lifeTime):
- self.lifeTime = lifeTime
-
- ##
- # get the lifetime of the credential
-
- def get_lifetime(self):
- if not self.lifeTime:
- self.decode()
- return self.lifeTime
-
- ##
- # set the delegate bit
- #
- # @param delegate boolean (True or False)
-
- def set_delegate(self, delegate):
- self.delegate = delegate
-
- ##
- # get the delegate bit
-
- def get_delegate(self):
- if not self.delegate:
- self.decode()
- return self.delegate
-
- ##
- # set the privileges
- #
- # @param privs either a comma-separated list of privileges of a Rights object
-
- def set_privileges(self, privs):
- if isinstance(privs, str):
- self.privileges = Rights(string = privs)
- else:
- self.privileges = privs
-
- ##
- # return the privileges as a Rights object
-
- def get_privileges(self):
- if not self.privileges:
- self.decode()
- return self.privileges
-
- ##
- # determine whether the credential allows a particular operation to be
- # performed
- #
- # @param op_name string specifying name of operation ("lookup", "update", etc)
-
- def can_perform(self, op_name):
- rights = self.get_privileges()
- if not rights:
- return False
- return rights.can_perform(op_name)
-
- ##
- # Encode the attributes of the credential into a string and store that
- # string in the alt-subject-name field of the X509 object. This should be
- # done immediately before signing the credential.
-
- def encode(self):
- dict = {"gidCaller": None,
- "gidObject": None,
- "lifeTime": self.lifeTime,
- "privileges": None,
- "delegate": self.delegate}
- if self.gidCaller:
- dict["gidCaller"] = self.gidCaller.save_to_string(save_parents=True)
- if self.gidObject:
- dict["gidObject"] = self.gidObject.save_to_string(save_parents=True)
- if self.privileges:
- dict["privileges"] = self.privileges.save_to_string()
- str = xmlrpclib.dumps((dict,), allow_none=True)
- self.set_data('URI:http://' + str)
-
- ##
- # Retrieve the attributes of the credential from the alt-subject-name field
- # of the X509 certificate. This is automatically done by the various
- # get_* methods of this class and should not need to be called explicitly.
-
- def decode(self):
- data = self.get_data().lstrip('URI:http://')
-
- if data:
- dict = xmlrpclib.loads(data)[0][0]
- else:
- dict = {}
-
- self.lifeTime = dict.get("lifeTime", None)
- self.delegate = dict.get("delegate", None)
-
- privStr = dict.get("privileges", None)
- if privStr:
- self.privileges = Rights(string = privStr)
- else:
- self.privileges = None
-
- gidCallerStr = dict.get("gidCaller", None)
- if gidCallerStr:
- self.gidCaller = GID(string=gidCallerStr)
- else:
- self.gidCaller = None
-
- gidObjectStr = dict.get("gidObject", None)
- if gidObjectStr:
- self.gidObject = GID(string=gidObjectStr)
- else:
- self.gidObject = None
-
- ##
- # Verify that a chain of credentials is valid (see cert.py:verify). In
- # addition to the checks for ordinary certificates, verification also
- # ensures that the delegate bit was set by each parent in the chain. If
- # a delegate bit was not set, then an exception is thrown.
- #
- # Each credential must be a subset of the rights of the parent.
-
- def verify_chain(self, trusted_certs = None):
- # do the normal certificate verification stuff
- Certificate.verify_chain(self, trusted_certs)
-
- if self.parent:
- # make sure the parent delegated rights to the child
- if not self.parent.get_delegate():
- raise MissingDelegateBit(self.parent.get_subject())
-
- # make sure the rights given to the child are a subset of the
- # parents rights
- if not self.parent.get_privileges().is_superset(self.get_privileges()):
- raise ChildRightsNotSubsetOfParent(self.get_subject()
- + " " + self.parent.get_privileges().save_to_string()
- + " " + self.get_privileges().save_to_string())
-
- return
-
- ##
- # Dump the contents of a credential to stdout in human-readable format
- #
- # @param dump_parents If true, also dump the parent certificates
-
- def dump(self, *args, **kwargs):
- print self.dump_string(*args,**kwargs)
-
- def dump_string(self, dump_parents=False):
- result=""
- result += "CREDENTIAL %s\n" % self.get_subject()
-
- result += " privs: %s\n" % self.get_privileges().save_to_string()
-
- gidCaller = self.get_gid_caller()
- if gidCaller:
- result += " gidCaller:\n"
- gidCaller.dump(8, dump_parents)
-
- gidObject = self.get_gid_object()
- if gidObject:
- result += " gidObject:\n"
- result += gidObject.dump_string(8, dump_parents)
-
- result += " delegate: %s" % self.get_delegate()
-
- if self.parent and dump_parents:
- result += "PARENT\n"
- result += self.parent.dump_string(dump_parents)
-
- return result
from xml.dom.minidom import *
from StringIO import StringIO
+from sfa.util.sfatime import SFATIME_FORMAT
+
from sfa.trust.certificate import Certificate
from sfa.trust.credential import Credential, signature_template, HAVELXML
from sfa.trust.abac_credential import ABACCredential, ABACElement
# Credential has not expired
if cred.expiration and cred.expiration < datetime.datetime.utcnow():
- return False, None, "ABAC Credential expired at %s (%s)" % (cred.expiration.isoformat(), cred.get_summary_tostring())
+ return False, None, "ABAC Credential expired at %s (%s)" % (cred.expiration.strftime(SFATIME_FORMAT), cred.get_summary_tostring())
# Must be ABAC
if cred.get_cred_type() != ABACCredential.ABAC_CREDENTIAL_TYPE:
credential_duration = datetime.timedelta(days=dur_days)
expiration = datetime.datetime.utcnow() + credential_duration
- expiration_str = expiration.strftime('%Y-%m-%dT%H:%M:%SZ') # FIXME: libabac can't handle .isoformat()
+ expiration_str = expiration.strftime(SFATIME_FORMAT)
version = "1.1"
user_keyid = get_cert_keyid(user_gid)
return False
- def dump(self, sections = []):
+ def dump(self, sections=None):
+ if sections is None: sections=[]
sys.stdout.write(output_python())
def output_python(self, encoding = "utf-8"):
# IN THE WORK.
#----------------------------------------------------------------------
from types import StringTypes
-import dateutil.parser
-import datetime
import time
+import datetime
+import dateutil.parser
+import calendar
import re
from sfa.util.sfalogging import logger
else:
logger.error("Unexpected type in utcparse [%s]"%type(input))
-def datetime_to_string(input):
- return datetime.datetime.strftime(input, SFATIME_FORMAT)
+def datetime_to_string(dt):
+ return datetime.datetime.strftime(dt, SFATIME_FORMAT)
-def datetime_to_utc(input):
- return time.gmtime(datetime_to_epoch(input))
+def datetime_to_utc(dt):
+ return time.gmtime(datetime_to_epoch(dt))
-def datetime_to_epoch(input):
- return int(time.mktime(input.timetuple()))
+# see https://docs.python.org/2/library/time.html
+# all timestamps are in UTC so time.mktime() would be *wrong*
+def datetime_to_epoch(dt):
+ return int(calendar.timegm(dt.timetuple()))
def add_datetime(input, days=0, hours=0, minutes=0, seconds=0):
"""
return dt + datetime.timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
if __name__ == '__main__':
+ # checking consistency
+ print 20*'X'
+ print ("Should be close to zero: %s"%(datetime_to_epoch(datetime.datetime.utcnow())-time.time()))
+ print 20*'X'
for input in [
'+2d',
'+3w',
db_filename = None
type = 'dict'
- def __init__(self, db_filename, db = {}):
-
+ def __init__(self, db_filename, db = None):
+ if db is None: db={}
dict.__init__(self, db)
self.db_filename = db_filename
scm_url="@SCMURL@"
import socket
-def version_core (more={}):
+def version_core (more=None):
+ if more is None: more={}
core = { 'code_tag' : version_tag,
'code_url' : scm_url,
'hostname' : socket.gethostname(),
return xpath
@staticmethod
- def xpath(filter={}):
+ def xpath(filter=None):
+ if filter is None: filter={}
xpath = ""
if filter:
filter_list = []
def getparent(self):
return XmlElement(self.element.getparent(), self.namespaces)
- def get_instance(self, instance_class=None, fields=[]):
+ def get_instance(self, instance_class=None, fields=None):
"""
Returns an instance (dict) of this xml element. The instance
holds a reference to this xml element.
"""
+ if fields is None: fields=[]
if not instance_class:
instance_class = Element
if not fields and hasattr(instance_class, 'fields'):
instance[field] = self.attrib[field]
return instance
- def add_instance(self, name, instance, fields=[]):
+ def add_instance(self, name, instance, fields=None):
"""
Adds the specifed instance(s) as a child element of this xml
element.
"""
+ if fields is None: fields=[]
if not fields and hasattr(instance, 'keys'):
fields = instance.keys()
elem = self.add_element(name)
return Xrn.urn_meaningful(urn).split('+')
@staticmethod
- def filter_type(urns=[], type=None):
+ def filter_type(urns=None, type=None):
+ if urns is None: urns=[]
urn_list = []
if not type:
return urns
<?xml version="1.0"?>
-<RSpec type="SFA" expires="2013-02-27T15:14:10Z" generated="2013-02-27T14:14:10Z">
+<RSpec type="SFA" expires="2014-52-27T15:14:10Z" generated="2013-05-19T14:14:10Z">
<network name="iotlab">
<node component_manager_id="urn:publicid:IDN+iotlab+authority+sa" component_id="urn:publicid:IDN+iotlab+node+wsn430-12.devlille.iot-lab.info" boot_state="Alive" component_name="wsn430-12.devlille.iot-lab.info" site_id="urn:publicid:IDN+senslab+authority+sa">
<hostname>wsn430-12.devlille.iot-lab.info</hostname>
<sliver/>
</node>
</network>
- <lease slice_id="urn:publicid:IDN+iotlab+slice+sandrine_slice" start_time="1405078836" duration="20">
+ <lease slice_id="urn:publicid:IDN+ple:upmc+slice+myslicedemo" start_time="1400604923" duration="20">
<node component_id="urn:publicid:IDN+iotlab+node+a8-11.devgrenoble.iot-lab.info"/>
<node component_id="urn:publicid:IDN+iotlab+node+wsn430-12.devlille.iot-lab.info"/>
</lease>