'geni_api_versions': {'3': 'http://%s:%s' % (socket.gethostname(), api.config.sfa_aggregate_port)},
'geni_single_allocation': 0, # Accept operations that act on as subset of slivers in a given state.
'geni_allocate': 'geni_many',# Multiple slivers can exist and be incrementally added, including those which connect or overlap in some way.
- 'geni_best_effort': 'true',
'geni_credential_types': cred_types,
}
version.update(version_generic)
hrn = urn_to_hrn(xrn)[0]
else:
hrn, type = urn_to_hrn(xrn)
-
+
+ # Slivers don't have credentials but users should be able to
+ # specify a sliver xrn and receive the slice's credential
+ if type == 'sliver' or '-' in Xrn(hrn).leaf:
+ slice_xrn = self.driver.sliver_to_slice_xrn(hrn)
+ hrn = slice_xrn.hrn
+
# Is this a root or sub authority
auth_hrn = api.auth.get_authority(hrn)
if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
else:
raise SfaInvalidArgument('Must specify an rspec version option. geni_rspec_version cannot be null')
- # Find the valid credentials
- valid_creds = self.api.auth.checkCredentials(creds, 'listnodes', urns)
+ valid_creds = self.api.auth.checkCredentials(creds, 'listnodes', urns, \
+ check_sliver_callback = self.api.manager.driver.check_sliver_credentials)
# get hrn of the original caller
origin_hrn = options.get('origin_hrn', None)
if NovaDriver.cache is None:
NovaDriver.cache = Cache()
self.cache = NovaDriver.cache
+
+ def sliver_to_slice_xrn(self, xrn):
+ return xrn
+
+ def check_sliver_credentials(self, creds, urns):
+ #TODO: Implement
+ return
########################################
########## registry oriented
xrn = PlXrn(xrn=urn)
if xrn.type == 'sliver':
# id: slice_id-node_id
- id_parts = xrn.leaf.split('-')
- slice_ids.add(id_parts[0])
- node_ids.append(id_parts[1])
+ sliver_id_parts = xrn.get_sliver_id_parts()
+ slice_ids.add(sliver_id_parts[0])
+ node_ids.append(sliver_id_parts[1])
else:
names.add(xrn.pl_slicename())
- if xrn.id:
- ids.add(xrn.id)
filter = {}
if names:
#
from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \
RecordNotFound, SfaNotImplemented, SliverDoesNotExist, SearchFailed, \
- UnsupportedOperation
+ UnsupportedOperation, Forbidden
from sfa.util.sfalogging import logger
from sfa.util.defaultdict import defaultdict
from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
if PlDriver.cache is None:
PlDriver.cache = Cache()
self.cache = PlDriver.cache
+
+ def sliver_to_slice_xrn(self, xrn):
+ sliver_id_parts = Xrn(xrn).get_sliver_id_parts()
+ slices = self.shell.GetSlices(sliver_id_parts[0])
+ if not slices:
+ raise Forbidden("Unable to locate slice record for sliver: %s" % xrn)
+ slice = slices[0]
+ slice_xrn = Xrn(auth=self.hrn, slicename=slice['name'])
+ return slice_xrn
+ def check_sliver_credentials(self, creds, urns):
+ # build list of cred object hrns
+ slice_cred_names = []
+ for cred in creds:
+ slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
+ slice_cred_names.append(PlXrn(xrn=slice_cred_hrn).pl_slicename())
+
+ # look slice names of slivers listed in urns arg
+ slice_ids = []
+ for urn in urns:
+ sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
+ slice_ids.append(sliver_id_parts[0])
+
+ if not slice_ids:
+ raise Forbidden("sliver urn not provided")
+
+ slices = self.shell.GetSlices(slice_ids)
+ sliver_names = [slice['name'] for slice in slices]
+
+ # make sure we have a credential for every specified sliver ierd
+ for sliver_name in sliver_names:
+ if sliver_name not in slice_cred_names:
+ msg = "Valid credential not found for target: %s" % sliver_name
+ raise Forbidden(msg)
+
########################################
########## registry oriented
########################################
import sys
from sfa.util.faults import InsufficientRights, MissingCallerGID, MissingTrustedRoots, PermissionError, \
- BadRequestHash, ConnectionKeyGIDMismatch, SfaPermissionDenied, CredentialNotVerifiable
+ BadRequestHash, ConnectionKeyGIDMismatch, SfaPermissionDenied, CredentialNotVerifiable, Forbidden
from sfa.util.sfalogging import logger
from sfa.util.config import Config
from sfa.util.xrn import Xrn, get_authority
self.trusted_cert_list = TrustedRoots(self.config.get_trustedroots_dir()).get_list()
self.trusted_cert_file_list = TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()
-
- def checkCredentials(self, creds, operation, xrns=[]):
+ def checkCredentials(self, creds, operation, xrns=[], check_sliver_callback=None):
if not isinstance(xrns, list):
xrns = [xrns]
- hrns = [Xrn(xrn).hrn for xrn in xrns]
+
+ 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
+ # we make sure not to include sliver urns/hrns in the core validation loop
+ hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns]
valid = []
if not isinstance(creds, list):
creds = [creds]
logger.debug("Auth.checkCredentials with %d creds on hrns=%s"%(len(creds),hrns))
# won't work if either creds or hrns is empty - let's make it more explicit
- if not creds: raise InsufficientRights("Access denied - no credential provided")
+ if not creds: raise Forbidden("no credential provided")
if not hrns: hrns = [None]
for cred in creds:
for hrn in hrns:
logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
error = sys.exc_info()[:2]
continue
-
+
+ # make sure all sliver xrns are validated against the valid credentials
+ if sliver_xrns:
+ if not check_sliver_callback:
+ msg = "sliver verification callback method not found."
+ msg += " Unable to validate sliver xrns: %s" % sliver_xrns
+ raise Forbidden(msg)
+ check_sliver_callback(valid, sliver_xrns)
+
if not len(valid):
- raise InsufficientRights('Access denied: %s -- %s' % (error[0],error[1]))
+ msg = "Valid credential not found for method: %s" % operation
+ if xrns:
+ msg += " target: %s" % xrns
+ raise Forbidden(msg)
return valid
def urn_split (urn):
return Xrn.urn_meaningful(urn).split('+')
+ @staticmethod
+ def filter_type(urns=[], type=None):
+ urn_list = []
+ if not type:
+ return urns
+
+ for urn in urns:
+ xrn = Xrn(xrn=urn)
+ if not xrn.type:
+ # If an xrn doesn't have a type its probably a hrn.
+ # We have to make some assumptions on the hrn's type
+ # based on the contents of the hrn.
+ if type == 'sliver' and '-' in xrn.leaf:
+ urn_list.append(urn)
+ elif type != 'sliver' and not '-' in xrn.leaf:
+ urn_list.append(urn)
+ elif (xrn.type == type):
+ # Xrn is probably a urn so we can just compare types
+ urn_list.append(urn)
+ return urn_list
####################
# the local fields that are kept consistent
# self.urn
self.hrn = hrn
self.hrn_to_urn()
self._normalize()
+
+ # sliver_id_parts is list that contains the sliver's
+ # slice id and node id
+ def get_sliver_id_parts(self):
+ sliver_id_parts = []
+ if self.type == 'sliver' or '-' in self.leaf:
+ sliver_id_parts = self.leaf.split('-')
+ return sliver_id_parts
+
def urn_to_hrn(self):
"""