def testGetSliverToolIdNone(self): tool_id = None slice_id = 'slice_id' server_id = 'server_id' site_id = 'site_id' self.assertIsNone( model.get_sliver_tool_id(tool_id, slice_id, server_id, site_id))
def initialize_sliver_tool(self, tool, site, server_id, fqdn): sliver_tool_id = model.get_sliver_tool_id(tool.tool_id, tool.slice_id, server_id, site.site_id) return model.SliverTool( tool_id=tool.tool_id, slice_id=tool.slice_id, site_id=site.site_id, server_id=server_id, fqdn=fqdn, server_port=tool.server_port, http_port=tool.http_port, # IP addresses will be updated by the IPUpdateHandler. sliver_ipv4=message.NO_IP_ADDRESS, sliver_ipv6=message.NO_IP_ADDRESS, # Status will be updated by the StatusUpdateHandler. status_ipv4=message.STATUS_OFFLINE, status_ipv6=message.STATUS_OFFLINE, tool_extra="", latitude=site.latitude, longitude=site.longitude, city=site.city, country=site.country, update_request_timestamp=long(time.time()), key_name=sliver_tool_id)
def initialize_sliver_tool(self, tool, site, server_id, fqdn): sliver_tool_id = model.get_sliver_tool_id(tool.tool_id, tool.slice_id, server_id, site.site_id) return model.SliverTool( tool_id=tool.tool_id, slice_id=tool.slice_id, site_id=site.site_id, server_id=server_id, fqdn=fqdn, server_port=tool.server_port, http_port=tool.http_port, # IP addresses will be updated by the IPUpdateHandler. sliver_ipv4=message.NO_IP_ADDRESS, sliver_ipv6=message.NO_IP_ADDRESS, # Status will be updated by the StatusUpdateHandler. status_ipv4=message.STATUS_OFFLINE, status_ipv6=message.STATUS_OFFLINE, tool_extra="", latitude=site.latitude, longitude=site.longitude, roundrobin=site.roundrobin, city=site.city, country=site.country, update_request_timestamp=long(time.time()), key_name=sliver_tool_id)
def test_no_update(self, mock_put, mock_initialize, mock_urlopen): mock_urlopen.return_value = StringIO.StringIO("""[ { "hostname": "ndt-iupui-mlab4-abc02.mlab-staging.measurement-lab.org", "ipv4": "192.168.0.1", "ipv6": "2002:AB:1234::1" } ]""") model.Site.all.return_value.fetch.return_value = [ mock.Mock(site_id='abc02', roundrobin=True) ] model.Tool.all.return_value.fetch.return_value = [ mock.Mock(slice_id='iupui_ndt', tool_id='ndt') ] mock_slivertools = mock.Mock( slice_id='iupui_ndt', tool_id='ndt', fqdn='ndt-iupui-mlab4-abc02.mlab-staging.measurement-lab.org', sliver_ipv4='192.168.0.1', sliver_ipv6='2002:AB:1234::1', roundrobin=True) sliver_tool_id = model.get_sliver_tool_id('ndt', 'iupui_ndt', 'mlab4', 'abc02') mock_slivertools.key.return_value.name.return_value = sliver_tool_id model.SliverTool.all.return_value.fetch.return_value = [ mock_slivertools ] handler = update.IPUpdateHandler() handler.update() self.assertFalse(mock_initialize.called) self.assertFalse(mock_put.called)
def testGetSliverToolIdValid(self): tool_id = 'tool_id' slice_id = 'slice_id' server_id = 'server_id' site_id = 'site_id' self.assertEqual( model.get_sliver_tool_id(tool_id, slice_id, server_id, site_id), 'tool_id-slice_id-server_id-site_id')
def update(self): """Triggers the update handler. Updates sliver tool IP addresses. """ try: hostnames_url = os.environ.get('HOSTNAMES_URL') raw_json = urllib2.urlopen(hostnames_url).read() logging.info('Fetched hostnames.json from: %s', hostnames_url) except urllib2.HTTPError: # TODO(claudiu) Notify(email) when this happens. logging.error('Cannot open %s.', hostnames_url) return util.send_not_found(self) try: rows = json.loads(raw_json) except (TypeError, ValueError) as e: logging.error('Failed to parse raw json from %s: %s', hostnames_url, e) return util.send_not_found(self) # Fetch all data that we are going to need from the datastore up front. sites = list(model.Site.all().fetch(limit=None)) tools = list(model.Tool.all().fetch(limit=None)) slivertools = list(model.SliverTool.all().fetch(limit=None)) for row in rows: # Expected keys: "hostname,ipv4,ipv6" (ipv6 can be an empty string). fqdn = row['hostname'] ipv4 = row['ipv4'] ipv6 = row['ipv6'] if not production_check.is_production_slice(fqdn): continue # Gather some information about this site which will be used to # determine if we need to do anything with this site/sliver. slice_id, site_id, server_id = \ model.get_slice_site_server_ids(fqdn) # Make sure this is a valid slice FQDN, and not a mistake or just a # node name. if slice_id is None or site_id is None or server_id is None: continue # If mlab-ns does not support this site, then skip it. site = list(filter(lambda s: s.site_id == site_id, sites)) if len(site) == 0: logging.info('mlab-ns does not support site %s.', site_id) continue else: site = site[0] # If mlab-ns does not serve/support this slice, then skip it. Note: # a given slice_id might have multiple tools (e.g., iupui_ndt has # both 'ndt' and 'ndt_ssl' tools. slice_tools = list(filter(lambda t: t.slice_id == slice_id, tools)) if len(slice_tools) == 0: continue for slice_tool in slice_tools: # See if this sliver_tool already exists in the datastore. sliver_tool_id = model.get_sliver_tool_id( slice_tool.tool_id, slice_id, server_id, site_id) slivertool = list(filter( lambda st: st.key().name() == sliver_tool_id, slivertools)) # If the sliver_tool already exists in the datastore, edit it. # If not, add it to the datastore. if len(slivertool) == 1: sliver_tool = slivertool[0] elif len(slivertool) == 0: logging.info( 'For tool %s, %s is not in datastore. Adding it.', slice_tool.tool_id, sliver_tool_id) sliver_tool = self.initialize_sliver_tool(slice_tool, site, server_id, fqdn) else: logging.error( 'Error, or too many sliver_tools returned for {}:{}.'.format( slice_tool.tool_id, sliver_tool_id)) continue updated_sliver_tool = self.set_sliver_tool( sliver_tool, ipv4, ipv6, site.roundrobin, fqdn) # Update datastore if the SliverTool got updated. if updated_sliver_tool: logging.info('Updating IP info for fqdn: %s', fqdn) self.put_sliver_tool(updated_sliver_tool) return