+ #
+ # Management of the servers
+ #
+
+ def registry (self):
+ # cache the result
+ if not hasattr (self, 'registry_proxy'):
+ self.logger.info("Contacting Registry at: %s"%self.reg_url)
+ self.registry_proxy = SfaServerProxy(self.reg_url, self.private_key, self.my_gid,
+ timeout=self.options.timeout, verbose=self.options.debug)
+ return self.registry_proxy
+
+ def sliceapi (self):
+ # cache the result
+ if not hasattr (self, 'sliceapi_proxy'):
+ # if the command exposes the --component option, figure it's hostname and connect at CM_PORT
+ if hasattr(self.command_options,'component') and self.command_options.component:
+ # resolve the hrn at the registry
+ node_hrn = self.command_options.component
+ records = self.registry().Resolve(node_hrn, self.my_credential_string)
+ records = filter_records('node', records)
+ if not records:
+ self.logger.warning("No such component:%r"% opts.component)
+ record = records[0]
+ cm_url = "http://%s:%d/"%(record['hostname'],CM_PORT)
+ self.sliceapi_proxy=SfaServerProxy(cm_url, self.private_key, self.my_gid)
+ else:
+ # otherwise use what was provided as --sliceapi, or SFI_SM in the config
+ if not self.sm_url.startswith('http://') or self.sm_url.startswith('https://'):
+ self.sm_url = 'http://' + self.sm_url
+ self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
+ self.sliceapi_proxy = SfaServerProxy(self.sm_url, self.private_key, self.my_gid,
+ timeout=self.options.timeout, verbose=self.options.debug)
+ return self.sliceapi_proxy
+
+ def get_cached_server_version(self, server):
+ # check local cache first
+ cache = None
+ version = None
+ cache_file = os.path.join(self.options.sfi_dir,'sfi_cache.dat')
+ cache_key = server.url + "-version"
+ try:
+ cache = Cache(cache_file)
+ except IOError:
+ cache = Cache()
+ self.logger.info("Local cache not found at: %s" % cache_file)
+
+ if cache:
+ version = cache.get(cache_key)
+
+ if not version:
+ result = server.GetVersion()
+ version= ReturnValue.get_value(result)
+ # cache version for 20 minutes
+ cache.add(cache_key, version, ttl= 60*20)
+ self.logger.info("Updating cache file %s" % cache_file)
+ cache.save_to_file(cache_file)
+
+ return version
+
+ ### resurrect this temporarily so we can support V1 aggregates for a while
+ def server_supports_options_arg(self, server):
+ """
+ Returns true if server support the optional call_id arg, false otherwise.
+ """
+ server_version = self.get_cached_server_version(server)
+ result = False
+ # xxx need to rewrite this
+ if int(server_version.get('geni_api')) >= 2:
+ result = True
+ return result
+
+ def server_supports_call_id_arg(self, server):
+ server_version = self.get_cached_server_version(server)
+ result = False
+ if 'sfa' in server_version and 'code_tag' in server_version:
+ code_tag = server_version['code_tag']
+ code_tag_parts = code_tag.split("-")
+ version_parts = code_tag_parts[0].split(".")
+ major, minor = version_parts[0], version_parts[1]
+ rev = code_tag_parts[1]
+ if int(major) == 1 and minor == 0 and build >= 22:
+ result = True
+ return result
+
+ ### ois = options if supported
+ # to be used in something like serverproxy.Method (arg1, arg2, *self.ois(api_options))
+ def ois (self, server, option_dict):
+ if self.server_supports_options_arg (server):
+ return [option_dict]
+ elif self.server_supports_call_id_arg (server):
+ return [ unique_call_id () ]
+ else:
+ return []
+
+ ### cis = call_id if supported - like ois
+ def cis (self, server):
+ if self.server_supports_call_id_arg (server):
+ return [ unique_call_id ]
+ else:
+ return []
+