From: Thierry Parmentelat Date: Mon, 31 Oct 2011 18:31:42 +0000 (+0100) Subject: solve merge conflict X-Git-Tag: sfa-1.1-2~17 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=f11dae03d2dc79be445c9a604c9c7fc4b222d98d;hp=1a4bcb040b5223cd23bf7219337215f16533f812;p=sfa.git solve merge conflict --- diff --git a/sfa.spec b/sfa.spec index a9271fc2..c470c497 100644 --- a/sfa.spec +++ b/sfa.spec @@ -1,6 +1,6 @@ %define name sfa %define version 1.1 -%define taglevel 0 +%define taglevel 1 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}} %global python_sitearch %( python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)" ) @@ -196,6 +196,11 @@ fi [ "$1" -ge "1" ] && service sfa-cm restart || : %changelog +* Fri Oct 28 2011 Thierry Parmentelat - sfa-1.1-1 +- first support for protogeni rspecs is working +- vini no longer needs a specific manager +- refactoring underway towards more flexible/generic architecture + * Thu Sep 15 2011 Tony Mack - sfa-1.0-36 - Unicode-friendliness for user names with accents/special chars. - Fix bug that could cause create the client to fail when calling CreateSliver for a slice that has the same hrn as a user. diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 0b447263..49392466 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -232,9 +232,9 @@ class Sfi: parser.add_option("-d", "--delegate", dest="delegate", default=None, action="store_true", help="Include a credential delegated to the user's root"+\ - "authority in set of credentials for this call") - - # registy filter option + "authority in set of credentials for this call") + + # registy filter option if command in ("list", "show", "remove"): parser.add_option("-t", "--type", dest="type", type="choice", help="type filter ([all]|user|slice|authority|node|aggregate)", @@ -521,7 +521,7 @@ class Sfi: if args: hrn = args[0] gid = self._get_gid(hrn) - self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True)) + self.logger.debug("Sfi.get_gid-> %s" % gid.save_to_string(save_parents=True)) return gid def _get_gid(self, hrn=None, type=None): @@ -985,10 +985,15 @@ class Sfi: slice_urn = hrn_to_urn(slice_hrn, 'slice') user_cred = self.get_user_cred() slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True) - # delegate the cred to the callers root authority - delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)+'.slicemanager') - #delegated_cred = self.delegate_cred(slice_cred, get_authority(slice_hrn)) - #creds.append(delegated_cred) + + if hasattr(opts, 'aggregate') and opts.aggregate: + delegated_cred = None + else: + # delegate the cred to the callers root authority + delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)+'.slicemanager') + #delegated_cred = self.delegate_cred(slice_cred, get_authority(slice_hrn)) + #creds.append(delegated_cred) + rspec_file = self.get_rspec_file(args[1]) rspec = open(rspec_file).read() @@ -1013,11 +1018,13 @@ class Sfi: creds = [slice_cred] else: users = sfa_users_arg(user_records, slice_record) - creds = [slice_cred, delegated_cred] + creds = [slice_cred] + if delegated_cred: + creds.append(delegated_cred) call_args = [slice_urn, creds, rspec, users] if self.server_supports_call_id_arg(server): call_args.append(unique_call_id()) - + result = server.CreateSliver(*call_args) if opts.file is None: print result diff --git a/sfa/client/sfiAddAttribute.py b/sfa/client/sfiAddAttribute.py index 9c2eae5c..f22e63e8 100755 --- a/sfa/client/sfiAddAttribute.py +++ b/sfa/client/sfiAddAttribute.py @@ -1,7 +1,6 @@ #! /usr/bin/env python import sys -from sfa.util.rspecHelper import RSpec, Commands from sfa.client.sfi_commands import Commands from sfa.rspecs.rspec import RSpec diff --git a/sfa/client/sfiAddLinks.py b/sfa/client/sfiAddLinks.py new file mode 100755 index 00000000..f5b28888 --- /dev/null +++ b/sfa/client/sfiAddLinks.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python + +import sys +from sfa.client.sfi_commands import Commands +from sfa.rspecs.rspec import RSpec +from sfa.rspecs.version_manager import VersionManager + +command = Commands(usage="%prog [options] node1 node2...", + description="Add links to the RSpec. " + + "This command reads in an RSpec and outputs a modified " + + "RSpec. Use this to add links to your slivers") +command.add_linkfile_option() +command.prep() + +if not command.opts.linkfile: + print "Missing link list -- exiting" + command.parser.print_help() + sys.exit(1) + +if command.opts.infile: + infile=file(command.opts.infile) +else: + infile=sys.stdin +if command.opts.outfile: + outfile=file(command.opts.outfile,"w") +else: + outfile=sys.stdout +ad_rspec = RSpec(infile) +links = file(command.opts.linkfile).read().split('\n') +link_tuples = map(lambda x: tuple(x.split()), links) + +version_manager = VersionManager() +try: + type = ad_rspec.version.type + version_num = ad_rspec.version.version + request_version = version_manager._get_version(type, version_num, 'request') + request_rspec = RSpec(version=request_version) + request_rspec.version.merge(ad_rspec) + request_rspec.version.add_link_requests(link_tuples) +except: + print >> sys.stderr, "FAILED: %s" % links + raise + sys.exit(1) +print >>outfile, request_rspec.toxml() +sys.exit(0) diff --git a/sfa/client/sfiListLinks.py b/sfa/client/sfiListLinks.py new file mode 100755 index 00000000..a4720ca1 --- /dev/null +++ b/sfa/client/sfiListLinks.py @@ -0,0 +1,26 @@ +#! /usr/bin/env python + +import sys +from sfa.client.sfi_commands import Commands +from sfa.rspecs.rspec import RSpec +from sfa.util.xrn import Xrn + +command = Commands(usage="%prog [options]", + description="List all links in the RSpec. " + + "Use this to display the list of available links. " ) +command.prep() + +if command.opts.infile: + rspec = RSpec(command.opts.infile) + links = rspec.version.get_links() + if command.opts.outfile: + sys.stdout = open(command.opts.outfile, 'w') + + for link in links: + ifname1 = Xrn(link['interface1']['component_id']).get_leaf() + ifname2 = Xrn(link['interface2']['component_id']).get_leaf() + print "%s %s" % (ifname1, ifname2) + + + + diff --git a/sfa/managers/aggregate_manager.py b/sfa/managers/aggregate_manager.py index 20db05cf..827b2d9e 100644 --- a/sfa/managers/aggregate_manager.py +++ b/sfa/managers/aggregate_manager.py @@ -188,6 +188,8 @@ def CreateSliver(api, slice_xrn, creds, rspec_string, users, call_id): requested_slivers = [str(host) for host in rspec.version.get_nodes_with_slivers()] slices.verify_slice_nodes(slice, requested_slivers, peer) + aggregate.prepare_nodes({'hostname': requested_slivers}) + aggregate.prepare_interfaces({'node_id': aggregate.nodes.keys()}) slices.verify_slice_links(slice, rspec.version.get_link_requests(), aggregate) # hanlde MyPLC peer association. @@ -324,31 +326,17 @@ def ListResources(api, creds, options, call_id): def get_ticket(api, xrn, creds, rspec, users): -#unused -# reg_objects = __get_registry_objects(xrn, creds, users) - (slice_hrn, _) = urn_to_hrn(xrn) -#unused -# slices = Slices(api) -# peer = slices.get_peer(slice_hrn) -# sfa_peer = slices.get_sfa_peer(slice_hrn) + slices = Slices(api) + peer = slices.get_peer(slice_hrn) + sfa_peer = slices.get_sfa_peer(slice_hrn) # get the slice record - registry = api.registries[api.hrn] credential = api.getCredential() + interface = api.registries[api.hrn] + registry = api.get_server(interface, credential) records = registry.Resolve(xrn, credential) - # similar to CreateSliver, we must verify that the required records exist - # at this aggregate before we can issue a ticket -#Error (E1121, get_ticket): Too many positional arguments for function call -#unused anyway -# site_id, remote_site_id = slices.verify_site(registry, credential, slice_hrn, -# peer, sfa_peer, reg_objects) -#Error (E1121, get_ticket): Too many positional arguments for function call -#unused anyway -# slice = slices.verify_slice(registry, credential, slice_hrn, site_id, -# remote_site_id, peer, sfa_peer, reg_objects) - # make sure we get a local slice record record = None for tmp_record in records: @@ -358,9 +346,25 @@ def get_ticket(api, xrn, creds, rspec, users): record = SliceRecord(dict=tmp_record) if not record: raise RecordNotFound(slice_hrn) + + # similar to CreateSliver, we must verify that the required records exist + # at this aggregate before we can issue a ticket + # parse rspec + rspec = RSpec(rspec_string) + requested_attributes = rspec.version.get_slice_attributes() + # ensure site record exists + site = slices.verify_site(hrn, slice_record, peer, sfa_peer) + # ensure slice record exists + slice = slices.verify_slice(hrn, slice_record, peer, sfa_peer) + # ensure person records exists + persons = slices.verify_persons(hrn, slice, users, peer, sfa_peer) + # ensure slice attributes exists + slices.verify_slice_attributes(slice, requested_attributes) + # get sliver info - slivers = Slices(api).get_slivers(slice_hrn) + slivers = slices.get_slivers(slice_hrn) + if not slivers: raise SliverDoesNotExist(slice_hrn) diff --git a/sfa/managers/registry_manager.py b/sfa/managers/registry_manager.py index e4a5b172..085bc39f 100644 --- a/sfa/managers/registry_manager.py +++ b/sfa/managers/registry_manager.py @@ -119,7 +119,9 @@ def resolve(api, xrns, type=None, full=True): xrns = xrn_dict[registry_hrn] if registry_hrn != api.hrn: credential = api.getCredential() - peer_records = registries[registry_hrn].Resolve(xrns, credential) + interface = api.registries[registry_hrn] + server = api.get_server(interface, credential) + peer_records = server.Resolve(xrns, credential) records.extend([SfaRecord(dict=record).as_dict() for record in peer_records]) # try resolving the remaining unfound records at the local registry @@ -155,13 +157,14 @@ def list(api, xrn, origin_hrn=None): #if there was no match then this record belongs to an unknow registry if not registry_hrn: raise MissingAuthority(xrn) - # if the best match (longest matching hrn) is not the local registry, # forward the request records = [] if registry_hrn != api.hrn: credential = api.getCredential() - record_list = registries[registry_hrn].List(xrn, credential) + interface = api.registries[registry_hrn] + server = api.get_server(interface, credential) + record_list = server.List(xrn, credential) records = [SfaRecord(dict=record).as_dict() for record in record_list] # if we still have not found the record yet, try the local registry diff --git a/sfa/managers/slice_manager.py b/sfa/managers/slice_manager.py index b84ef716..29113138 100644 --- a/sfa/managers/slice_manager.py +++ b/sfa/managers/slice_manager.py @@ -8,7 +8,6 @@ from sfa.trust.sfaticket import SfaTicket from sfa.trust.credential import Credential from sfa.util.sfalogging import logger -from sfa.util.rspecHelper import merge_rspecs from sfa.util.xrn import Xrn, urn_to_hrn from sfa.util.threadmanager import ThreadManager from sfa.util.version import version_core @@ -434,7 +433,7 @@ def get_ticket(api, xrn, creds, rspec, users): results = threads.get_results() # gather information from each ticket - rspecs = [] + rspec = None initscripts = [] slivers = [] object_gid = None @@ -443,15 +442,17 @@ def get_ticket(api, xrn, creds, rspec, users): attrs = agg_ticket.get_attributes() if not object_gid: object_gid = agg_ticket.get_gid_object() - rspecs.append(agg_ticket.get_rspec()) + if not rspec: + rspec = RSpec(agg_ticket.get_rspec()) + else: + rspec.version.merge(agg_ticket.get_rspec()) initscripts.extend(attrs.get('initscripts', [])) slivers.extend(attrs.get('slivers', [])) # merge info attributes = {'initscripts': initscripts, 'slivers': slivers} - merged_rspec = merge_rspecs(rspecs) - + # create a new ticket ticket = SfaTicket(subject = slice_hrn) ticket.set_gid_caller(api.auth.client_gid) @@ -460,7 +461,7 @@ def get_ticket(api, xrn, creds, rspec, users): ticket.set_pubkey(object_gid.get_pubkey()) #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn)) ticket.set_attributes(attributes) - ticket.set_rspec(merged_rspec) + ticket.set_rspec(rspec.toxml()) ticket.encode() ticket.sign() return ticket.save_to_string(save_parents=True) diff --git a/sfa/plc/aggregate.py b/sfa/plc/aggregate.py index 77784cb6..f210705b 100644 --- a/sfa/plc/aggregate.py +++ b/sfa/plc/aggregate.py @@ -25,14 +25,26 @@ class Aggregate: self.api = api self.user_options = user_options - def prepare_sites(self, force=False): + def prepare_sites(self, filter={}, force=False): if not self.sites or force: - for site in self.api.plshell.GetSites(self.api.plauth): + for site in self.api.plshell.GetSites(self.api.plauth, filter): self.sites[site['site_id']] = site - def prepare_nodes(self, force=False): + def prepare_nodes(self, filter={}, force=False): if not self.nodes or force: - for node in self.api.plshell.GetNodes(self.api.plauth, {'peer_id': None}): + filter.update({'peer_id': None}) + nodes = self.api.plshell.GetNodes(self.api.plauth, filter) + site_ids = [] + interface_ids = [] + tag_ids = [] + for node in nodes: + site_ids.append(node['site_id']) + interface_ids.extend(node['interface_ids']) + tag_ids.extend(node['node_tag_ids']) + self.prepare_sites({'site_id': site_ids}) + self.prepare_interfaces({'interface_id': interface_ids}) + self.prepare_node_tags({'node_tag_id': tag_ids}) + for node in nodes: # add site/interface info to nodes. # assumes that sites, interfaces and tags have already been prepared. site = self.sites[node['site_id']] @@ -47,12 +59,12 @@ class Aggregate: node['tags'] = tags self.nodes[node['node_id']] = node - def prepare_interfaces(self, force=False): + def prepare_interfaces(self, filter={}, force=False): if not self.interfaces or force: - for interface in self.api.plshell.GetInterfaces(self.api.plauth): + for interface in self.api.plshell.GetInterfaces(self.api.plauth, filter): self.interfaces[interface['interface_id']] = interface - def prepare_links(self, force=False): + def prepare_links(self, filter={}, force=False): if not self.links or force: if not self.api.config.SFA_AGGREGATE_TYPE.lower() == 'vini': return @@ -73,10 +85,12 @@ class Aggregate: # set interfaces # just get first interface of the first node if1_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node1['node_id'])) + if1_ipv4 = self.interfaces[node1['interface_ids'][0]]['ip'] if2_xrn = PlXrn(auth=self.api.hrn, interface='node%s:eth0' % (node2['node_id'])) + if2_ipv4 = self.interfaces[node2['interface_ids'][0]]['ip'] - if1 = Interface({'component_id': if1_xrn.urn} ) - if2 = Interface({'component_id': if2_xrn.urn} ) + if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} ) + if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} ) # set link link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'}) @@ -88,28 +102,36 @@ class Aggregate: self.links[link['component_name']] = link - def prepare_node_tags(self, force=False): + def prepare_node_tags(self, filter={}, force=False): if not self.node_tags or force: - for node_tag in self.api.plshell.GetNodeTags(self.api.plauth): + for node_tag in self.api.plshell.GetNodeTags(self.api.plauth, filter): self.node_tags[node_tag['node_tag_id']] = node_tag - def prepare_pl_initscripts(self, force=False): + def prepare_pl_initscripts(self, filter={}, force=False): if not self.pl_initscripts or force: - for initscript in self.api.plshell.GetInitScripts(self.api.plauth, {'enabled': True}): + filter.update({'enabled': True}) + for initscript in self.api.plshell.GetInitScripts(self.api.plauth, filter): self.pl_initscripts[initscript['initscript_id']] = initscript - def prepare(self, force=False): - if not self.prepared or force: - self.prepare_sites(force) - self.prepare_interfaces(force) - self.prepare_node_tags(force) - self.prepare_nodes(force) - self.prepare_links(force) - self.prepare_pl_initscripts() - self.prepared = True + def prepare(self, slice = None, force=False): + if not self.prepared or force or slice: + if not slice: + self.prepare_sites(force=force) + self.prepare_interfaces(force=force) + self.prepare_node_tags(force=force) + self.prepare_nodes(force=force) + self.prepare_links(force=force) + self.prepare_pl_initscripts(force=force) + else: + self.prepare_sites({'site_id': slice['site_id']}) + self.prepare_interfaces({'node_id': slice['node_ids']}) + self.prepare_node_tags({'node_id': slice['node_ids']}) + self.prepare_nodes({'node_id': slice['node_ids']}) + self.prepare_links({'slice_id': slice['slice_id']}) + self.prepare_pl_initscripts() + self.prepared = True def get_rspec(self, slice_xrn=None, version = None): - self.prepare() version_manager = VersionManager() version = version_manager.get_version(version) if not slice_xrn: @@ -125,8 +147,11 @@ class Aggregate: slice_name = hrn_to_pl_slicename(slice_hrn) slices = self.api.plshell.GetSlices(self.api.plauth, slice_name) if slices: - slice = slices[0] - + slice = slices[0] + self.prepare(slice=slice) + else: + self.prepare() + # filter out nodes with a whitelist: valid_nodes = [] for node in self.nodes.values(): diff --git a/sfa/plc/slices.py b/sfa/plc/slices.py index 5edce647..5cead3be 100644 --- a/sfa/plc/slices.py +++ b/sfa/plc/slices.py @@ -6,6 +6,7 @@ from sfa.util.plxrn import hrn_to_pl_slicename from sfa.util.policy import Policy from sfa.rspecs.rspec import RSpec from sfa.plc.vlink import VLink +from sfa.util.xrn import Xrn MAXINT = 2L**31-1 @@ -185,10 +186,20 @@ class Slices: def verify_slice_links(self, slice, links, aggregate): # nodes is undefined here - if not links or not aggregate.nodes: + if not links: return + for link in links: - topo_rspec = VLink.get_topo_rspec(link) + # get the ip address of the first node in the link + ifname1 = Xrn(link['interface1']['component_id']).get_leaf() + (node, device) = ifname1.split(':') + node_id = int(node.replace('node', '')) + node = aggregate.nodes[node_id] + if1 = aggregate.interfaces[node['interface_ids'][0]] + ipaddr = if1['ip'] + topo_rspec = VLink.get_topo_rspec(link, ipaddr) + self.api.plshell.AddSliceTag(self.api.plauth, slice['name'], 'topo_rspec', str([topo_rspec]), node_id) + def handle_peer(self, site, slice, persons, peer): diff --git a/sfa/plc/vlink.py b/sfa/plc/vlink.py index 73ebae79..625963d0 100644 --- a/sfa/plc/vlink.py +++ b/sfa/plc/vlink.py @@ -1,4 +1,4 @@ - +import re from sfa.util.xrn import Xrn # Taken from bwlimit.py # @@ -79,34 +79,37 @@ class VLink: @staticmethod def get_virt_ip(if1, if2): - link_id = get_link_id(if1, if2) - iface_id = get_iface_id(if1, if2) + link_id = VLink.get_link_id(if1, if2) + iface_id = VLink.get_iface_id(if1, if2) first = link_id >> 6 second = ((link_id & 0x3f)<<2) + iface_id - return "192.168.%d.%s" % (frist, second) + return "192.168.%d.%s" % (first, second) @staticmethod def get_virt_net(link): - link_id = self.get_link_id(link) + link_id = VLink.get_link_id(link['interface1'], link['interface2']) first = link_id >> 6 second = (link_id & 0x3f)<<2 return "192.168.%d.%d/30" % (first, second) @staticmethod def get_interface_id(interface): - if_name = Xrn(interface=interface['component_id']).get_leaf() + if_name = Xrn(interface['component_id']).get_leaf() node, dev = if_name.split(":") - node_id = int(node.replace("pc", "")) + node_id = int(node.replace("node", "")) return node_id @staticmethod - def get_topo_rspec(link): + def get_topo_rspec(link, ipaddr): link['interface1']['id'] = VLink.get_interface_id(link['interface1']) link['interface2']['id'] = VLink.get_interface_id(link['interface2']) my_ip = VLink.get_virt_ip(link['interface1'], link['interface2']) remote_ip = VLink.get_virt_ip(link['interface2'], link['interface1']) net = VLink.get_virt_net(link) bw = format_tc_rate(long(link['capacity'])) - ipaddr = remote.get_primary_iface().ipv4 - return (link['interface2']['id'], ipaddr, bw, my_ip, remote_ip, net) + return (link['interface2']['id'], ipaddr, bw, my_ip, remote_ip, net) + + @staticmethod + def topo_rspec_to_link(topo_rspec): + pass diff --git a/sfa/rspecs/elements/versions/pgv2Link.py b/sfa/rspecs/elements/versions/pgv2Link.py index e39ef35d..aeef7602 100644 --- a/sfa/rspecs/elements/versions/pgv2Link.py +++ b/sfa/rspecs/elements/versions/pgv2Link.py @@ -17,9 +17,8 @@ class PGv2Link: @staticmethod def add_links(xml, links): - root = xml.root for link in links: - link_elem = etree.SubElement(root, 'link') + link_elem = etree.SubElement(xml, 'link') for attrib in ['component_name', 'component_id', 'client_id']: if attrib in link and link[attrib] is not None: link_elem.set(attrib, link[attrib]) @@ -38,7 +37,6 @@ class PGv2Link: latency=link['latency'], packet_loss=link['packet_loss']) if 'type' in link and link['type']: type_elem = etree.SubElement(link_elem, 'link_type', name=link['type']) - @staticmethod def get_links(xml): links = [] @@ -87,18 +85,16 @@ class PGv2Link: available_links = PGv2Link.get_links(xml) recently_added = [] for link in available_links: - auth = Xrn(link['component_id']).get_authority_hrn() if_name1 = Xrn(link['interface1']['component_id']).get_leaf() if_name2 = Xrn(link['interface2']['component_id']).get_leaf() - + requested_link = None l_tup_1 = (if_name1, if_name2) - l_tup_2 = (if_name2, if_name1) + l_tup_2 = (if_name2, if_name1) if link_tuples.issuperset([(if_name1, if_name2)]): requested_link = (if_name1, if_name2) elif link_tuples.issuperset([(if_name2, if_name2)]): requested_link = (if_name2, if_name1) - if requested_link: # add client id to link ane interface elements link.element.set('client_id', link['component_name']) diff --git a/sfa/rspecs/versions/pgv2.py b/sfa/rspecs/versions/pgv2.py index af5b367e..b57cd9bb 100644 --- a/sfa/rspecs/versions/pgv2.py +++ b/sfa/rspecs/versions/pgv2.py @@ -99,10 +99,10 @@ class PGv2(BaseVersion): return PGv2Link.get_link_requests(self.xml) def add_links(self, links): - PGv2Link.add_links(self.xml, links) + PGv2Link.add_links(self.xml.root, links) def add_link_requests(self, link_tuples, append=False): - PGv2Link.add_link_requests(self.xml, link_tuples, append) + PGv2Link.add_link_requests(self.xml.root, link_tuples, append) def attributes_list(self, elem): opts = [] diff --git a/sfa/rspecs/versions/sfav1.py b/sfa/rspecs/versions/sfav1.py index c3bb2084..3917b39b 100644 --- a/sfa/rspecs/versions/sfav1.py +++ b/sfa/rspecs/versions/sfav1.py @@ -1,3 +1,4 @@ +from copy import deepcopy from lxml import etree from sfa.util.xrn import hrn_to_urn, urn_to_hrn from sfa.util.plxrn import PlXrn @@ -217,7 +218,8 @@ class SFAv1(BaseVersion): if 'bwlimit' in interface and interface['bwlimit']: bwlimit = etree.SubElement(node_tag, 'bw_limit', units='kbps').text = str(interface['bwlimit']/1000) comp_id = PlXrn(auth=network, interface='node%s:eth%s' % (node['node_id'], i)).get_urn() - interface_tag = etree.SubElement(node_tag, 'interface', component_id=comp_id) + ipaddr = interface['ip'] + interface_tag = etree.SubElement(node_tag, 'interface', component_id=comp_id, ipv4=ipaddr) i+=1 if 'bw_unallocated' in node: bw_unallocated = etree.SubElement(node_tag, 'bw_unallocated', units='kbps').text = str(node['bw_unallocated']/1000) @@ -245,7 +247,15 @@ class SFAv1(BaseVersion): pass def add_links(self, links): - PGv2Link.add_links(self.xml, links) + networks = self.get_network_elements() + if len(networks) > 0: + xml = networks[0] + else: + xml = self.xml + PGv2Link.add_links(xml, links) + + def add_link_requests(self, links): + PGv2Link.add_link_requests(self.xml, links) def add_slivers(self, slivers, network=None, sliver_urn=None, no_dupes=False, append=False): # add slice name to network tag diff --git a/sfa/server/interface.py b/sfa/server/interface.py index 7d2beef6..94302ecf 100644 --- a/sfa/server/interface.py +++ b/sfa/server/interface.py @@ -1,6 +1,6 @@ #from sfa.util.faults import * -from sfa.util.storage import XmlStorage import sfa.util.xmlrpcprotocol as xmlrpcprotocol +from sfa.util.xml import XML # GeniLight client support is optional try: @@ -57,25 +57,20 @@ class Interfaces(dict): def __init__(self, conf_file): dict.__init__(self, {}) # load config file - self.interface_info = XmlStorage(conf_file, self.default_dict) - self.interface_info.load() - records = self.interface_info.values()[0] - if not isinstance(records, list): - records = [records] - - required_fields = self.default_fields.keys() - for record in records: - if not record or not set(required_fields).issubset(record.keys()): - continue - # port is appended onto the domain, before the path. Should look like: - # http://domain:port/path - hrn, address, port = record['hrn'], record['addr'], record['port'] - # sometime this is called at a very early stage with no config loaded - # avoid to remember this instance in such a case - if not address or not port: - continue - interface = Interface(hrn, address, port) - self[hrn] = interface + required_fields = set(self.default_fields.keys()) + self.interface_info = XML(conf_file).todict() + for value in self.interface_info.values(): + if isinstance(value, list): + for record in value: + if isinstance(record, dict) and \ + required_fields.issubset(record.keys()): + hrn, address, port = record['hrn'], record['addr'], record['port'] + # sometime this is called at a very early stage with no config loaded + # avoid to remember this instance in such a case + if not address or not port: + continue + interface = Interface(hrn, address, port) + self[hrn] = interface def get_server(self, hrn, key_file, cert_file, timeout=30): return self[hrn].get_server(key_file, cert_file, timeout) diff --git a/sfa/util/cache.py b/sfa/util/cache.py index 0383ccce..a2ded4a4 100644 --- a/sfa/util/cache.py +++ b/sfa/util/cache.py @@ -82,9 +82,18 @@ class Cache: def get(self, key): data = self.cache.get(key) - if not data or data.is_expired(): - return None - return data.get_data() + if not data: + data = None + elif data.is_expired(): + self.pop(key) + data = None + else: + data = data.get_data() + return data + + def pop(self, key): + if key in self.cache: + self.cache.pop(key) def dump(self): result = {} diff --git a/sfa/util/record.py b/sfa/util/record.py index 54c3f9f7..7ebf379a 100644 --- a/sfa/util/record.py +++ b/sfa/util/record.py @@ -279,6 +279,7 @@ class SfaRecord(Row): """ Load the record from a dictionary """ + self.set_name(dict['hrn']) gidstr = dict.get("gid", None) if gidstr: @@ -316,7 +317,7 @@ class SfaRecord(Row): representation of the record. """ #dict = xmlrpclib.loads(str)[0][0] - + record = XML(str) self.load_from_dict(record.todict()) diff --git a/sfa/util/xml.py b/sfa/util/xml.py index 78e4c6a2..8f51ce39 100755 --- a/sfa/util/xml.py +++ b/sfa/util/xml.py @@ -96,8 +96,15 @@ class XML: elif isinstance(value, int): d[key] = unicode(d[key]) elif value is None: - d.pop(key) - + d.pop(key) + + # element.attrib.update will explode if DateTimes are in the + # dcitionary. + d=d.copy() + for k in d.keys(): + if (type(d[k]) != str) and (type(d[k]) != unicode): + del d[k] + element.attrib.update(d) def validate(self, schema): @@ -209,6 +216,7 @@ class XML: def toxml(self): return etree.tostring(self.root, encoding='UTF-8', pretty_print=True) + # XXX smbaker, for record.load_from_string def todict(self, elem=None): if elem is None: elem = self.root @@ -219,7 +227,11 @@ class XML: if child.tag not in d: d[child.tag] = [] d[child.tag].append(self.todict(child)) - return d + + if len(d)==1 and ("text" in d): + d = d["text"] + + return d def save(self, filename): f = open(filename, 'w')