2 from datetime import datetime, timedelta
3 from sfa.rspecs.xml_interface import XMLInterface, XpathFilter
4 from sfa.rspecs.version_manager import VersionManager
5 from sfa.util.xrn import *
6 from sfa.util.plxrn import hostname_to_urn
7 from sfa.rspecs.rspec_elements import RSpecElement, RSpecElements
8 from sfa.util.faults import SfaNotImplemented, InvalidRSpec, InvalidRSpecElement
10 class RSpec(XMLInterface):
12 def __init__(self, rspec="", version=None, user_options={}):
13 self.header = '<?xml version="1.0"?>\n'
14 self.template = """<RSpec></RSpec>"""
17 self.version_manager = VersionManager()
18 self.user_options = user_options
25 def create(self, version=None):
29 self.version = self.version_manager.get_version(version)
30 self.namespaces = self.version.namespaces
31 self.parse_xml(self.version.template)
32 # eg. 2011-03-23T19:53:28Z
33 date_format = '%Y-%m-%dT%H:%M:%SZ'
34 now = datetime.utcnow()
35 generated_ts = now.strftime(date_format)
36 expires_ts = (now + timedelta(hours=1)).strftime(date_format)
37 self.xml.set('expires', expires_ts)
38 self.xml.set('generated', generated_ts)
41 def parse_xml(self, xml):
42 XMLInterface.parse_xml(self, xml)
43 # determine rspec version
44 # look for schema first
47 for key in self.xml.attrib.keys():
48 if key.endswith('schemaLocation'):
49 # schema location should be at the end of the list
50 schema_parts = self.xml.attrib[key].split(' ')
51 namespace, schema = schema_parts[0], schema_parts[1]
55 self.version = self.version_manager.get_version_by_schema(schema)
57 # TODO: probably isn't safe to assume use default version here
58 # should probably fault if we arent certain
59 self.version = self.version_manager.get_version()
60 self.version.xml = self.xml
61 self.namespaces = self.version.namespaces
63 def load_rspec_elements(self, rspec_elements):
65 for rspec_element in rspec_elements:
66 if isinstance(rspec_element, RSpecElement):
67 self.elements[rspec_element.type] = rspec_element
69 def register_rspec_element(self, element_type, element_name, element_path):
70 if element_type not in RSpecElements:
71 raise InvalidRSpecElement(element_type, extra="no such element type: %s. Must specify a valid RSpecElement" % element_type)
72 self.elements[element_type] = RSpecElement(element_type, element_name, element_path)
74 def get_rspec_element(self, element_type):
75 if element_type not in self.elements:
76 msg = "ElementType %s not registerd for this rspec" % element_type
77 raise InvalidRSpecElement(element_type, extra=msg)
78 return self.elements[element_type]
80 def get(self, element_type, filter={}, depth=0):
81 elements = self.get_elements(element_type, filter)
82 elements = [self.get_element_attributes(element, depth=depth) for element in elements]
85 def get_elements(self, element_type, filter={}):
87 search for a registered element
89 if element_type not in self.elements:
90 msg = "Unable to search for element %s in rspec, expath expression not found." % \
92 raise InvalidRSpecElement(element_type, extra=msg)
93 rspec_element = self.get_rspec_element(element_type)
94 xpath = rspec_element.path + XpathFilter.xpath(filter)
95 return self.xpath(xpath)
97 def merge(self, in_rspec):
100 def _process_slivers(self, slivers):
102 Creates a dict of sliver details for each sliver host
104 @param slivers a single hostname, list of hostanmes or list of dicts keys on hostname,
105 Returns a list of dicts
107 if not isinstance(slivers, list):
110 for sliver in slivers:
111 if isinstance(sliver, dict):
113 elif isinstance(sliver, basestring):
114 dicts.append({'hostname': sliver})
117 if __name__ == '__main__':
118 rspec = RSpec('/tmp/resources.rspec')
120 rspec.register_rspec_element(RSpecElements.NETWORK, 'network', '//network')
121 rspec.register_rspec_element(RSpecElements.NODE, 'node', '//node')
122 print rspec.get(RSpecElements.NODE)[0]
123 print rspec.get(RSpecElements.NODE, depth=1)[0]