%define name sfa
%define version 3.1
-%define taglevel 21
+%define taglevel 22
%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
+* Fri Mar 16 2018 Thierry <Parmentelat> - sfa-3.1-22
+- pl: tweaks for exposing country / city on nodes from site tags if set
+- pl: tweaks for exposing hardware_types on nodes from node tag 'hardware_type' if set
+- pl: fix exposing granularity
+- sfaresetgids.py: a utility to reset gids when a update of the tolpevel gis is needed
+- iotlab: various tweaks
+- patch backported from plcapi about issues with xmlrpc and unicode under fedora >= 24
+
* Fri Jan 13 2017 Thierry Parmentelat <thierry.parmentelat@sophia.inria.fr> - sfa-3.1-21
- sfax509 command can run openssl x509 on all the parts of a gid
- bugfix in sfi when running the discover subcommand
-import socket
+# pylint: disable=c0111, c0103, r0201
+
from sfa.rspecs.version_manager import VersionManager
from sfa.util.version import version_core
from sfa.util.xrn import Xrn
class AggregateManager:
- def __init__(self, config): pass
+ def __init__(self, config):
+ pass
# essentially a union of the core version, the generic version (this code) and
# whatever the driver needs to expose
ad_rspec_versions = []
request_rspec_versions = []
for rspec_version in version_manager.versions:
+ # avoid publishing non-relevant entries
+ # but stay safe however
+ try:
+ if not rspec_version.extensions \
+ and not rspec_version.namespace \
+ and not rspec_version.schema:
+ continue
+ except Exception as exc:
+ pass
if rspec_version.content_type in ['*', 'ad']:
ad_rspec_versions.append(rspec_version.to_dict())
if rspec_version.content_type in ['*', 'request']:
cred_types = [{'geni_type': 'geni_sfa',
'geni_version': str(i)} for i in range(4)[-2:]]
geni_api_versions = ApiVersions().get_versions()
- geni_api_versions[
- '3'] = 'http://%s:%s' % (api.config.sfa_aggregate_host, api.config.sfa_aggregate_port)
+ geni_api_versions['3'] = \
+ 'https://%s:%s' % (api.config.sfa_aggregate_host, api.config.sfa_aggregate_port)
version_generic = {
'testbed': api.driver.testbed_name(),
'interface': 'aggregate',
def Allocate(self, api, xrn, creds, rspec_string, expiration, options):
"""
- Allocate resources as described in a request RSpec argument
+ Allocate resources as described in a request RSpec argument
to a slice with the named URN.
"""
call_id = options.get('call_id')
def Provision(self, api, xrns, creds, options):
"""
- Create the sliver[s] (slice) at this aggregate.
+ Create the sliver[s] (slice) at this aggregate.
Verify HRN and initialize the slice record in PLC if necessary.
"""
call_id = options.get('call_id')
'interface': 'slicemgr',
'sfa': 2,
'geni_api': 3,
- 'geni_api_versions': {'3': 'http://%s:%s' % (api.config.SFA_SM_HOST, api.config.SFA_SM_PORT)},
+ 'geni_api_versions': {'3': 'https://%s:%s' % (api.config.SFA_SM_HOST, api.config.SFA_SM_PORT)},
'hrn': xrn.get_hrn(),
'urn': xrn.get_urn(),
'peers': peers,
# slice-global tags
node['slice-tags'] = pltags_dict['slice-global']
# xxx
- # this is where we chould maybe add the nodegroup slice tags,
+ # this is where we should maybe add the nodegroup slice tags,
# but it's tedious...
# xxx
# sliver tags
else:
rspec_node['exclusive'] = 'false'
- rspec_node['hardware_types'] = [HardwareType({'name': 'plab-pc'}),
- HardwareType({'name': 'pc'})]
+ # expose hardware_types from the hardware_type tag if
+ # set on node
+ tags = self.driver.shell.GetNodeTags({
+ 'node_id': node['node_id'],
+ 'tagname': 'hardware_type',
+ })
+ if tags:
+ rspec_node['hardware_types'] = [
+ HardwareType({'name': tags[0]['value']}),
+ ]
+ else:
+ rspec_node['hardware_types'] = [
+ HardwareType({'name': 'plab-pc'}),
+ HardwareType({'name': 'pc'})
+ ]
# only doing this because protogeni rspec needs
# to advertise available initscripts
rspec_node['pl_initscripts'] = pl_initscripts.values()
# add site/interface info to nodes.
# assumes that sites, interfaces and tags have already been prepared.
if site['longitude'] and site['latitude']:
- location = Location({'longitude': site['longitude'], 'latitude': site[
- 'latitude'], 'country': 'unknown'})
+ location_dict = {
+ 'longitude': site['longitude'],
+ 'latitude': site['latitude'],
+ }
+ for extra in ('country', 'city'):
+ try:
+ tags = self.driver.shell.GetSiteTags({
+ 'site_id' : site['site_id'],
+ 'tagname' : extra,
+ })
+ location_dict[extra] = tags[0]['value']
+ except:
+ logger.log_exc('extra = {}'.format(extra))
+ location_dict[extra] = 'unknown'
+ location = Location(location_dict)
rspec_node['location'] = location
# Granularity
granularity = Granularity({'grain': grain})
node_tags = self.get_node_tags({'node_tag_id': tag_ids})
pl_initscripts = self.get_pl_initscripts()
# convert nodes to rspec nodes
+ grain = self.driver.shell.GetLeaseGranularity()
rspec_nodes = []
for node in nodes:
rspec_node = self.node_to_rspec_node(
- node, sites, interfaces, node_tags, pl_initscripts)
+ node, sites, interfaces, node_tags, pl_initscripts, grain)
rspec_nodes.append(rspec_node)
rspec.version.add_nodes(rspec_nodes)
'UnBindObjectFromPeer', 'UpdateNode', 'UpdatePerson', 'UpdateSite',
'UpdateSlice', 'UpdateSliceTag',
# also used as-is in importer
- 'GetSites', 'GetNodes',
+ 'GetSites', 'GetNodes', 'GetSiteTags',
# Lease management methods
'GetLeases', 'GetLeaseGranularity', 'DeleteLeases', 'UpdateLeases',
'AddLeases',
'country',
'longitude',
'latitude',
+ 'city',
]
from sfa.server.aggregate import Aggregates
from sfa.client.return_value import ReturnValue
-# after http://www.erlenstar.demon.co.uk/unix/faq_2.html
-
def daemon():
- """Daemonize the current process."""
+ """
+ Daemonize the current process.
+ after http://www.erlenstar.demon.co.uk/unix/faq_2.html
+ """
if os.fork() != 0:
os._exit(0)
os.setsid()
xrns = []
error = (None, None)
- def log_invalid_cred(cred):
+ def log_invalid_cred(cred, exception):
if not isinstance(cred, StringType):
logger.info(
- "cannot validate credential %s - expecting a string" % cred)
+ "{}: cannot validate credential {}"
+ .format(exception, cred))
error = ('TypeMismatch',
- "checkCredentials: expected a string, received {} -- {}"
+ "checkCredentials: expected a string, got {} -- {}"
.format(type(cred), cred))
else:
cred_obj = Credential(string=cred)
- logger.info("failed to validate credential - dump=%s" %
- cred_obj.dump_string(dump_parents=True))
+ logger.info("{}: failed to validate credential dump={}"
+ .format(exception,
+ cred_obj.dump_string(dump_parents=True)))
error = sys.exc_info()[:2]
return error
if not isinstance(xrns, list):
xrns = [xrns]
- slice_xrns = Xrn.filter_type(xrns, 'slice')
+ # slice_xrns = Xrn.filter_type(xrns, 'slice')
sliver_xrns = Xrn.filter_type(xrns, 'sliver')
# we are not able to validate slivers in the traditional way so
try:
self.check(cred, operation, hrn)
valid.append(cred)
- except:
- error = log_invalid_cred(cred)
+ except Exception as exc:
+ error = log_invalid_cred(cred, exc)
# make sure all sliver xrns are validated against the valid credentials
if sliver_xrns:
def check(self, credential, operation, hrn=None):
"""
- Check the credential against the peer cert (callerGID) included
- in the credential matches the caller that is connected to the
- HTTPS connection, check if the credential was signed by a
- trusted cert and check if the credential is allowed to perform
- the specified operation.
+ Check the credential against the peer cert (callerGID) included
+ in the credential matches the caller that is connected to the
+ HTTPS connection, check if the credential was signed by a
+ trusted cert and check if the credential is allowed to perform
+ the specified operation.
"""
cred = Credential(cred=credential)
self.client_cred = cred
Given an authority name, return the information for that authority.
This is basically a stub that calls the hierarchy module.
- @param auth_hrn human readable name of authority
+ @param auth_hrn human readable name of authority
"""
return self.hierarchy.get_auth_info(auth_hrn)
def veriry_auth_belongs_to_me(self, name):
"""
- Verify that an authority belongs to our hierarchy.
+ Verify that an authority belongs to our hierarchy.
This is basically left up to the implementation of the hierarchy
- module. If the specified name does not belong, ane exception is
+ module. If the specified name does not belong, ane exception is
thrown indicating the caller should contact someone else.
@param auth_name human readable name of authority
this implies that the authority that owns the object belongs
to our hierarchy. If it does not an exception is thrown.
- @param name human readable name of object
+ @param name human readable name of object
"""
auth_name = self.get_authority(name)
if not auth_name:
"""
Verify that the object gid that was specified in the credential
allows permission to the object 'name'. This is done by a simple
- prefix test. For example, an object_gid for plc.arizona would
+ prefix test. For example, an object_gid for plc.arizona would
match the objects plc.arizona.slice1 and plc.arizona.
- @param name human readable name to test
+ @param name human readable name to test
"""
object_hrn = self.object_gid.get_hrn()
if object_hrn == name:
def filter_creds_by_caller(self, creds, caller_hrn_list):
"""
- Returns a list of creds who's gid caller matches the
+ Returns a list of creds who's gid caller matches the
specified caller hrn
"""
if not isinstance(creds, list):
self.logger.addHandler(handler)
-info_logger = _SfaLogger(loggername='info', level=logging.INFO)
-debug_logger = _SfaLogger(loggername='debug', level=logging.DEBUG)
-warn_logger = _SfaLogger(loggername='warning', level=logging.WARNING)
-error_logger = _SfaLogger(loggername='error', level=logging.ERROR)
-critical_logger = _SfaLogger(loggername='critical', level=logging.CRITICAL)
-logger = info_logger
+logger = _SfaLogger(loggername='info', level=logging.INFO)
+
sfi_logger = _SfaLogger(logfile=os.path.expanduser("~/.sfi/") + 'sfi.log',
loggername='sfilog', level=logging.DEBUG)
########################################
self.type = type
self.hrn_to_urn()
self._normalize()
-# happens all the time ..
-# if not type:
-# debug_logger.debug("type-less Xrn's are not safe")
def __repr__(self):
result = "<XRN u=%s h=%s" % (self.urn, self.hrn)