Beispiel #1
0
    def renew_slivers(self, slice_object, sliver_objects, creds,
                      expiration_time, options):
        """
            AM API V3 method.

            Set the expiration time of the specified slivers to the specified
            value.  If the slice credentials expire before the specified
            expiration time, set sliver expiration times to the slice 
            credentials expiration time.
        """
        expiration = utils.min_expire(creds, self._max_lease_time,
                                      expiration_time)

        # Lock this slice so nobody else can mess with it while we renew
        with slice_object.getLock():
            for sliver in sliver_objects:
                sliver.setExpiration(expiration)

            # Create a sliver status list for the slivers that were renewed
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(sliver_objects)

            requested = utils._naiveUTC(dateutil.parser.parse(expiration_time))

            # If geni_extend_alap option provided, use the earlier
            # of the requested time and max expiration as the expiration time
            if 'geni_extend_alap' in options and options['geni_extend_alap']:
                if expiration < requested:
                    slice_urn = slice_object.getSliceURN()
                    config.logger.info(
                        "Got geni_extend_alap: revising slice %s renew request from %s to %s"
                        % (slice_urn, requested, expiration))
                requested = expiration

            if requested > expiration:
                config.logger.info('expiration time too long')
                code = {'geni_code': constants.REQUEST_PARSE_FAILED}
                return {
                    'code':
                    code,
                    'value':
                    sliver_status_list,
                    'output':
                    'ERROR: Requested sliver expiration is greater than either the slice expiration or the maximum lease time: '
                    + str(config.lease_expiration_minutes) + ' minutes'
                }

            code = {'geni_code': constants.SUCCESS}
            return {'code': code, 'value': sliver_status_list, 'output': ''}
Beispiel #2
0
    def renew_slivers(self,slice_object, sliver_objects, creds, expiration_time, options):
        """
            AM API V3 method.

            Set the expiration time of the specified slivers to the specified
            value.  If the slice credentials expire before the specified
            expiration time, set sliver expiration times to the slice 
            credentials expiration time.
        """
        expiration = utils.min_expire(creds, self._max_lease_time,
                                      expiration_time)

        # Lock this slice so nobody else can mess with it while we renew
        with slice_object.getLock() :
            for sliver in sliver_objects :
                sliver.setExpiration(expiration)

            # Create a sliver status list for the slivers that were renewed
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(sliver_objects)

            requested = utils._naiveUTC(dateutil.parser.parse(expiration_time))

            # If geni_extend_alap option provided, use the earlier           
            # of the requested time and max expiration as the expiration time
            if 'geni_extend_alap' in options and options['geni_extend_alap']:
                if expiration < requested:
                    slice_urn = slice_object.getSliceURN()
                    config.logger.info("Got geni_extend_alap: revising slice %s renew request from %s to %s" % (slice_urn, requested, expiration))
                requested = expiration

            if requested > expiration:
                config.logger.info('expiration time too long')
                code = {'geni_code':constants.REQUEST_PARSE_FAILED}
                return {'code':code, 'value':sliver_status_list, 'output':'ERROR: Requested sliver expiration is greater than either the slice expiration or the maximum lease time: ' + str(config.lease_expiration_minutes) + ' minutes'}

            code = {'geni_code': constants.SUCCESS}
            return {'code': code, 'value': sliver_status_list, 'output':''}
Beispiel #3
0
    def provision(self, slice_object, sliver_objects, creds, options):
        """
            AM API V3 method.

            Provision the slivers listed in sliver_objects, if they have
            not already been provisioned.
        """
        if len(sliver_objects) == 0:
            # No slivers specified: Return error message
            code = {'geni_code': constants.REQUEST_PARSE_FAILED}
            err_str = 'No slivers to be provisioned.'
            return {'code': code, 'value': '', 'output': err_str}

        # Make sure slivers have been allocated before we provision them.
        # Return an error if even one of the slivers has not been allocated
        for sliver in sliver_objects:
            if sliver.getAllocationState() != constants.allocated:
                # Found a sliver that has not been allocated.  Return with error.
                code = {'geni_code': constants.REQUEST_PARSE_FAILED}
                err_str = 'Slivers to be provisioned must have allocation state geni_allocated'
                return {'code': code, 'value': '', 'output': err_str}

        # See if the geni_users option has been set.  This option is used to
        # specify user accounts to be created on virtual machines that are
        # provisioned by this call
        if options.has_key('geni_users'):
            users = options['geni_users']
        else:
            users = list()

        # Lock this slice so nobody else can mess with it during provisioning
        with slice_object.getLock():
            err_str = open_stack_interface.provisionResources(
                slice_object, sliver_objects, users, self)
            if err_str != None:
                # We failed to provision this slice for some reason (described
                # in err_str)
                code = {'geni_code': constants.OPENSTACK_ERROR}
                self.delete(slice_object, sliver_objects, options)
                return {'code': code, 'value': '', 'output': err_str}

            # Set expiration times on the provisioned resources
            # Set expiration times on the allocated resources
            expiration = utils.min_expire(
                creds, self._max_lease_time, 'geni_end_time' in options
                and options['geni_end_time'])
            for sliver in sliver_objects:
                sliver.setExpiration(expiration)

            # Generate a manifest rpsec
            req_rspec = slice_object.getRequestRspec()
            manifest, error_string, error_code =  \
                rspec_handler.generateManifestForSlivers(slice_object,
                                                         sliver_objects,
                                                         True,
                                                         False,
                                                         self._aggregate_urn,
                                                         self._stitching)

            if error_code != constants.SUCCESS:
                return {
                    'code': {
                        'geni_code': error_code
                    },
                    'value': "",
                    'output': error_string
                }

            # Create a sliver status list for the slivers that were provisioned
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(sliver_objects)

            # Persist new GramManager state
            self.persist_state()

            # Report the new slice to VMOC
            self.registerSliceToVMOC(slice_object)

            # Generate the return struct
            code = {'geni_code': constants.SUCCESS}
            result_struct = {'geni_rspec':manifest, \
                                 'geni_slivers':sliver_status_list}
            return {'code': code, 'value': result_struct, 'output': ''}
Beispiel #4
0
    def allocate(self, slice_urn, creds, rspec, options):
        """
            AM API V3 method.

            Request reservation of GRAM resources.  We assume that by the 
            time we get here the caller's credentials have been verified 
            by the gcf framework (see am3.py).

            Returns None if successful.
            Returns an error string on failure.
        """
        config.logger.info('Allocate called for slice %r' % slice_urn)

        # Grab user urn out of slice credentail
        user_urn = None
        if len(creds) == 1:
            user_urn = creds[0].gidCaller.urn

        # Check if we already have slivers for this slice
        slice_object = SliceURNtoSliceObject.get_slice_object(slice_urn)
        if slice_object == None:
            # This is a new slice at this aggregate.  Create Slice object
            # and add it the list of slices at this AM
            slice_object = Slice(slice_urn)
            SliceURNtoSliceObject.set_slice_object(slice_urn, slice_object)

        # Lock this slice so nobody else can mess with it during allocation
        with slice_object.getLock():
            # Parse the request rspec.  Get back any error message from parsing
            # the rspec and a list of slivers created while parsing
            # Also OF controller, if any
            err_output, err_code, slivers, controller_link_info = \
                rspec_handler.parseRequestRspec(self._aggregate_urn,
                                                slice_object, rspec,
                                                self._stitching)

            if err_output != None:
                # Something went wrong.  First remove from the slice any sliver
                # objects created while parsing the bad rspec
                self.cleanup_slivers(slivers, slice_object)

                # Return an error struct.
                code = {'geni_code': err_code}
                return {'code': code, 'value': '', 'output': err_output}

            # If we're associating an OpenFlow controller to
            # any link of this slice,
            # Each VM must go on its own host. If there are more nodes
            # than hosts, we fail
            if len(controller_link_info) > 0:
                hosts = open_stack_interface._listHosts('compute')
                num_vms = 0
                for sliver in slivers:
                    if isinstance(sliver, VirtualMachine):
                        num_vms = num_vms + 1
                if len(hosts) < num_vms:
                    # Fail: More VMs requested than compute hosts
                    # on rack.  Remove from this slice the sliver
                    # objects created during this call to allocate
                    # before returning an error struct
                    self.cleanup_slivers(slivers, slice_object)
                    code = {'geni_code': constants.REQUEST_PARSE_FAILED}
                    error_output = \
                        "For OpenFlow controlled slice, limit of " + \
                        str(len(hosts)) + " VM's"
                    return {'code': code, 'value': '', 'output': error_output}

            # Set the experimenter provider controller URL (if any)
            for link_object in slice_object.getNetworkLinks():
                link_name = link_object.getName()
                if link_name in controller_link_info:
                    controller_url_for_link = controller_link_info[link_name]
                    link_object.setControllerURL(controller_url_for_link)

            # Set expiration times on the allocated resources
            expiration = utils.min_expire(
                creds, self._max_alloc_time, 'geni_end_time' in options
                and options['geni_end_time'])
            for sliver in slivers:
                sliver.setExpiration(expiration)

                # Set expiration time on the slice itself
                slice_object.setExpiration(expiration)

            # Associate an external VLAN tag with every
            # stitching link
#            print 'allocating external vlan'
# Allocate external vlans and set them on the slivers
            is_v2_allocation = 'AM_API_V2' in options
            for link_sliver_object in slice_object.getNetworkLinks():
                success, error_string, error_code = \
                    self._stitching.allocate_external_vlan_tags(link_sliver_object, \
                                                                    rspec, is_v2_allocation)
                if not success:
                    self.cleanup_slivers(slivers, slice_object)
                    return {
                        'code': {
                            'geni_code': error_code
                        },
                        'value': "",
                        'output': error_string
                    }

            # Associate an internal VLAN tag with every link
            # that isn't already set by stitching
#            print 'allocating internal vlan'
            if not self.allocate_internal_vlan_tags(slice_object):
                self.cleanup_slivers(slivers, slice_object)
                error_string = "No more internal VLAN tags available"
                error_code = constants.VLAN_UNAVAILABLE
                return {
                    'code': {
                        'geni_code': error_code
                    },
                    'value': "",
                    'output': error_string
                }

            # Generate a manifest rspec
            slice_object.setRequestRspec(rspec)
            for sliver in slivers:
                sliver.setRequestRspec(rspec)
            agg_urn = self._aggregate_urn
            # At this point, we don't allocate VLAN's: they should already be allocated
            manifest, error_string, error_code =  \
                rspec_handler.generateManifestForSlivers(slice_object, \
                                                             slivers, True, \
                                                             False,
                                                             agg_urn, \
                                                             self._stitching)
            if error_code != constants.SUCCESS:
                self.cleanup_slivers(slivers, slice_object)
                return {
                    'code': {
                        'geni_code': error_code
                    },
                    'value': "",
                    'output': error_string
                }

            slice_object.setManifestRspec(manifest)

            # Set the user urn for all new slivers
            all_slice_slivers = slice_object.getAllSlivers()
            for sliver_urn in all_slice_slivers:
                sliver = all_slice_slivers[sliver_urn]
                if not sliver.getUserURN():
                    sliver.setUserURN(user_urn)

            # Persist aggregate state
            self.persist_state()

            # Create a sliver status list for the slivers allocated by this call
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(slivers)

            # Generate the return struct
            code = {'geni_code': constants.SUCCESS}
            result_struct = {
                'geni_rspec': manifest,
                'geni_slivers': sliver_status_list
            }
            return {'code': code, 'value': result_struct, 'output': ''}
Beispiel #5
0
    def provision(self, slice_object, sliver_objects, creds, options) :
        """
            AM API V3 method.

            Provision the slivers listed in sliver_objects, if they have
            not already been provisioned.
        """
        if len(sliver_objects) == 0 :
            # No slivers specified: Return error message
            code = {'geni_code': constants.REQUEST_PARSE_FAILED}
            err_str = 'No slivers to be provisioned.'
            return {'code': code, 'value': '', 'output': err_str}

        # Make sure slivers have been allocated before we provision them.
        # Return an error if even one of the slivers has not been allocated
        for sliver in sliver_objects :
            if sliver.getAllocationState() != constants.allocated :
                # Found a sliver that has not been allocated.  Return with error.
                code = {'geni_code': constants.REQUEST_PARSE_FAILED}
                err_str = 'Slivers to be provisioned must have allocation state geni_allocated'
                return {'code': code, 'value': '', 'output': err_str}
                
        # See if the geni_users option has been set.  This option is used to
        # specify user accounts to be created on virtual machines that are
        # provisioned by this call
        if options.has_key('geni_users'):
            users = options['geni_users']
        else :
            users = list()
        
        # Lock this slice so nobody else can mess with it during provisioning
        with slice_object.getLock() :
	    err_str = provision_interface.provisionResources(slice_object, sliver_objects, users, self)
           # err_str = open_stack_interface.provisionResources(slice_object,
           #                                                   sliver_objects,
           #                                                   users, self)
           # if err_str != None :
                # We failed to provision this slice for some reason (described
                # in err_str)
           #     code = {'geni_code': constants.OPENSTACK_ERROR}
           #     self.delete(slice_object, sliver_objects, options)        
           #     return {'code': code, 'value': '', 'output': err_str}
    
            # Set expiration times on the provisioned resources
            # Set expiration times on the allocated resources
            expiration = utils.min_expire(creds, self._max_lease_time,
                         'geni_end_time' in options and options['geni_end_time'])
            for sliver in sliver_objects :
                sliver.setExpiration(expiration)

            # Generate a manifest rpsec 
            req_rspec = slice_object.getRequestRspec()
            manifest, error_string, error_code =  \
                rspec_handler.generateManifestForSlivers(slice_object,
                                                         sliver_objects,
                                                         True,
                                                         False,
                                                         self._aggregate_urn,
                                                         self._stitching)

            if error_code != constants.SUCCESS:
                return {'code' : {'geni_code' : error_code}, 'value' : "", 
                        'output' : error_string}
    
            # Create a sliver status list for the slivers that were provisioned
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(sliver_objects)

            # Persist new GramManager state
            self.persist_state()

            # Report the new slice to VMOC
            self.registerSliceToVMOC(slice_object)

            # Generate the return struct
            code = {'geni_code': constants.SUCCESS}
            result_struct = {'geni_rspec':manifest, \
                                 'geni_slivers':sliver_status_list}
            return {'code': code, 'value': result_struct, 'output': ''}
Beispiel #6
0
    def allocate(self, slice_urn, creds, rspec, options) :

        """
            AM API V3 method.

            Request reservation of GRAM resources.  We assume that by the 
            time we get here the caller's credentials have been verified 
            by the gcf framework (see am3.py).

            Returns None if successful.
            Returns an error string on failure.
        """
        config.logger.info('Allocate called for slice %r' % slice_urn)

        # Grab user urn out of slice credentail
        user_urn  = None
        if len(creds) == 1:
            user_urn = creds[0].gidCaller.urn

        # Check if we already have slivers for this slice
        slice_object = SliceURNtoSliceObject.get_slice_object(slice_urn)
        if slice_object == None :
            # This is a new slice at this aggregate.  Create Slice object 
            # and add it the list of slices at this AM
            slice_object = Slice(slice_urn)
            SliceURNtoSliceObject.set_slice_object(slice_urn, slice_object)

        # Lock this slice so nobody else can mess with it during allocation
        with slice_object.getLock() :
            # Parse the request rspec.  Get back any error message from parsing
            # the rspec and a list of slivers created while parsing
            # Also OF controller, if any
            err_output, err_code, slivers, controller_link_info = \
                rspec_handler.parseRequestRspec(self._aggregate_urn,
                                                slice_object, rspec, 
                                                self._stitching)

            if err_output != None :
                # Something went wrong.  First remove from the slice any sliver
                # objects created while parsing the bad rspec
                self.cleanup_slivers(slivers, slice_object)
                
                # Return an error struct.
                code = {'geni_code': err_code}
                return {'code': code, 'value': '', 'output': err_output}

            # If we're associating an OpenFlow controller to 
            # any link of this slice, 
            # Each VM must go on its own host. If there are more nodes
            # than hosts, we fail
            if len(controller_link_info) > 0:
                hosts = open_stack_interface._listHosts('compute')
                num_vms = 0
                for sliver in slivers:
                    if isinstance(sliver, VirtualMachine):
                        num_vms = num_vms + 1
                if len(hosts) < num_vms:
                    # Fail: More VMs requested than compute hosts 
                    # on rack.  Remove from this slice the sliver 
                    # objects created during this call to allocate 
                    # before returning an error struct
                    self.cleanup_slivers(slivers, slice_object)
                    code =  {'geni_code': constants.REQUEST_PARSE_FAILED}
                    error_output = \
                        "For OpenFlow controlled slice, limit of " + \
                        str(len(hosts)) + " VM's"
                    return {'code': code, 'value':'', 
                                'output':error_output}
        
            # Set the experimenter provider controller URL (if any)
            for link_object in slice_object.getNetworkLinks():
                link_name = link_object.getName()
                if link_name in controller_link_info:
                    controller_url_for_link = controller_link_info[link_name]
                    link_object.setControllerURL(controller_url_for_link)

            # Set expiration times on the allocated resources
            expiration = utils.min_expire(creds, 
                         self._max_alloc_time,
                         'geni_end_time' in options and options['geni_end_time'])
            for sliver in slivers :
                sliver.setExpiration(expiration)

            # Set expiration time on the slice itself
                slice_object.setExpiration(expiration);

            # Associate an external VLAN tag with every 
            # stitching link
#            print 'allocating external vlan'
            # Allocate external vlans and set them on the slivers
            is_v2_allocation = 'AM_API_V2' in options
            for link_sliver_object in slice_object.getNetworkLinks():
                success, error_string, error_code = \
                    self._stitching.allocate_external_vlan_tags(link_sliver_object, \
                                                                    rspec, is_v2_allocation)
                if not success:
                    self.cleanup_slivers(slivers, slice_object)
                    return {'code' : {'geni_code' : error_code}, 'value' : "",
                            'output' : error_string}

            # Associate an internal VLAN tag with every link 
            # that isn't already set by stitching
#            print 'allocating internal vlan'
            if not self.allocate_internal_vlan_tags(slice_object):
                self.cleanup_slivers(slivers, slice_object)
                error_string = "No more internal VLAN tags available"
                error_code = constants.VLAN_UNAVAILABLE
                return {'code' : {'geni_code' : error_code}, 'value' : "",
                        'output' : error_string}
 
            # Generate a manifest rspec
            slice_object.setRequestRspec(rspec)
            for sliver in slivers:
                sliver.setRequestRspec(rspec);
            agg_urn = self._aggregate_urn
            # At this point, we don't allocate VLAN's: they should already be allocated
            manifest, error_string, error_code =  \
                rspec_handler.generateManifestForSlivers(slice_object, \
                                                             slivers, True, \
                                                             False,
                                                             agg_urn, \
                                                             self._stitching)
            if error_code != constants.SUCCESS:
                self.cleanup_slivers(slivers, slice_object)
                return {'code' : {'geni_code' : error_code}, 'value' : "", 
                        'output' : error_string}

            slice_object.setManifestRspec(manifest)

            # Set the user urn for all new slivers
            all_slice_slivers = slice_object.getAllSlivers()
            for sliver_urn in all_slice_slivers:
                sliver = all_slice_slivers[sliver_urn]
                if not sliver.getUserURN():
                    sliver.setUserURN(user_urn)

            # Persist aggregate state
            self.persist_state()

            # Create a sliver status list for the slivers allocated by this call
            sliver_status_list = \
                utils.SliverList().getStatusOfSlivers(slivers)


            # Generate the return struct
            code = {'geni_code': constants.SUCCESS}
            result_struct = {'geni_rspec':manifest,
                             'geni_slivers':sliver_status_list}
            return {'code': code, 'value': result_struct, 'output': ''}