def test___init__(self): """LindenServer.__init__ should set the server's hostname and associate with the server class""" server = ClassXServer("test1.lindenlab.com") self.assertEquals(server.server_class.name, "Class X Server", "Server was not properly associated with its server class.") self.assertEquals(server.hostname, "test1.lindenlab.com", "Hostname was not properly set.") self.assertEquals(llclusto.get_by_hostname("test1.lindenlab.com"), [server], "Cannot find server by using llclusto.get_by_hostname()") # Test whether I'm able to create a server whose _server_class_name does not exist. self.assertRaises(LookupError, lambda: ClassYServer("test2.lindenlab.com")) self.assertEquals(llclusto.get_by_hostname("test2.lindenlab.com"), [], "When creation of a ClassYServer failed because there is no ServerClass named Class Y Server, the ClassYServer entity was still created (transaction should have been rolled back).")
def __init__(self, hostname=None, **kwargs): """Create a new server. hostname: The hostname for this server. """ try: clusto.begin_transaction() if hostname: servers = llclusto.get_by_hostname(hostname) else: servers = [] if len(servers) > 0: raise ValueError("One or more servers with hostname %s already exist: %s" % (hostname, servers)) super(LindenServer, self).__init__(**kwargs) self.hostname = hostname self.server_class = ServerClass.get_server_class(self._server_class_name) clusto.commit() except: clusto.rollback_transaction() raise
def rollback_host_image(request, hostname): """Rollback image association to previous pgi image. Returns: None Arguments: hostname -- the hostname formatted as a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching hostname. JinxInvalidStateError -- more than one host was found matching the hostname. -- no image was previously associated with this host. """ hosts = llclusto.get_by_hostname(hostname) if len(hosts) < 1: return HttpResponseNotFound("Hostname '%s' does not exist" % hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % hostname) host = hosts[0] try: host.revert_pgi_image() except RevertPGIImageError as e: return HttpResponseInvalidState(str(e)) return
def _get_host_instance(request, hostname_or_mac): """ Function that returns an instance from either a hostname or mac address. Arguments: hostname_or_mac -- The hostname or MAC address of the host. Exceptions Raised: JinxDataNotFoundError -- A host matching the specified hostname or MAC address could not be found. JinxInvalidStateError -- More than one host had the specified hostname or mac address. """ hosts = None if re.match(r'[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}', hostname_or_mac, re.I): # Looks like it might be a mac, try mac address first hosts = clusto.get_by_mac(hostname_or_mac) if not hosts: # If I haven't found it yet, it must be a hostname: hosts = llclusto.get_by_hostname(hostname_or_mac) if not hosts: return HttpResponseNotFound('No host was found with hostname or MAC address "%s".' % hostname_or_mac) elif len(hosts) > 1: return HttpResponseInvalidState('More than one host found with hostname or MAC address "%s".' % hostname_or_mac) else: host = hosts[0] return host
def add_si_image(request, si_hostname, image_name): """Adds image to systemimager. Returns: None Arguments: si_hostname -- the systemimager hostname formatted as a string. image_name -- the image name formatted at a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching systemimager hostname or image_name. JinxInvalidStateError -- more than one host was found matching the hostname. """ hosts = llclusto.get_by_hostname(si_hostname) if len(hosts) < 1: return HttpResponseNotFound("Systemimager hostname '%s' does not exist" % si_hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % si_hostname) host = hosts[0] try: image = clusto.get_by_name(image_name) except LookupError: image = PGIImage(image_name) host.add_stored_pgi_image(image) return
def get_si_images(request, si_hostname): """Gets a lists of all images on a systemimager. Returns: A list of image names formatted as strings. Arguments: si_hostname -- the hostname of the systemimager formatted as a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching hostname. JinxInvalidStateError -- more than one host was found matching the hostname. """ hosts = llclusto.get_by_hostname(si_hostname) if len(hosts) < 1: return HttpResponseNotFound("Systemimager hostname '%s' does not exist" % si_hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % si_hostname) host = hosts[0] images = [] for image in host.get_stored_pgi_images(): images.append(image.name) return images
def get_current_pgi_image(request, hostname): """Returns the image assoicated with the hostname passed in. Returns: A string containing the associated image name. Arguments: hostname -- the hostname formatted as a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching hostname. JinxInvalidStateError -- more than one host was found matching the hostname. """ hosts = llclusto.get_by_hostname(hostname) if len(hosts) < 1: return HttpResponseNotFound("Hostname '%s' does not exist" % hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % hostname) host = hosts[0] if host.pgi_image is None: return None return host.pgi_image.name
def update_host_image_association(request, hostname, image_name): """Associate a host with the pgi image. Returns: None Arguments: hostname -- the hostname formatted as a string. image_name -- the image name formatted at a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching hostname or image_name. JinxInvalidStateError -- more than one host was found matching the hostname. """ hosts = llclusto.get_by_hostname(hostname) if len(hosts) < 1: return HttpResponseNotFound("Hostname '%s' does not exist" % hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % hostname) host = hosts[0] try: image = clusto.get_by_name(image_name) except LookupError: return HttpResponseNotFound("Image '%s' does not exist." % image_name) host.pgi_image = image return
def __init__(self, hostname=None, **kwargs): """Create a new server. hostname: The hostname for this server. """ try: clusto.begin_transaction() if hostname: servers = llclusto.get_by_hostname(hostname) else: servers = [] if len(servers) > 0: raise ValueError( "One or more servers with hostname %s already exist: %s" % (hostname, servers)) super(LindenServer, self).__init__(**kwargs) self.hostname = hostname self.server_class = ServerClass.get_server_class( self._server_class_name) clusto.commit() except: clusto.rollback_transaction() raise
def test_normal_call(self): response = self.do_api_call("sim8000.agni.lindenlab.com", "aa:bb:cc:11:22:33") self.assert_response_code(response, 200) host = llclusto.get_by_hostname("sim8000.agni.lindenlab.com")[0] self.assertEquals(host.hostname, "sim8000.agni.lindenlab.com") mac = host.get_port_attr('nic-eth', 1, 'mac') self.assertEquals(mac, "aa:bb:cc:11:22:33") # Set a hostname on nic-eth 2. response = self.do_api_call("sim4000.agni.lindenlab.com", "aa:bb:cc:11:22:34") self.assert_response_code(response, 200) host = llclusto.get_by_hostname("sim4000.agni.lindenlab.com")[0] mac = host.get_port_attr('nic-eth', 2, 'mac') self.assertEquals(mac, "aa:bb:cc:11:22:34")
def testGetByHostname(self): d1 = TestLLClusto() d1.hostname = 'foo' s1 = llclusto.get_by_hostname('foo') self.assertEqual(len(s1), 1) self.assertEqual(s1[0], d1)
def test___init__(self): """LindenServer.__init__ should set the server's hostname and associate with the server class""" server = ClassXServer("test1.lindenlab.com") self.assertEquals( server.server_class.name, "Class X Server", "Server was not properly associated with its server class.") self.assertEquals(server.hostname, "test1.lindenlab.com", "Hostname was not properly set.") self.assertEquals( llclusto.get_by_hostname("test1.lindenlab.com"), [server], "Cannot find server by using llclusto.get_by_hostname()") # Test whether I'm able to create a server whose _server_class_name does not exist. self.assertRaises(LookupError, lambda: ClassYServer("test2.lindenlab.com")) self.assertEquals( llclusto.get_by_hostname("test2.lindenlab.com"), [], "When creation of a ClassYServer failed because there is no ServerClass named Class Y Server, the ClassYServer entity was still created (transaction should have been rolled back)." )
def set_dhcp_association(request, hostname, mac_address): """ Function that sets a hostname to a specified mac_address. Arguments: hostname -- The hostname of an entity. mac_address -- The mac_address of an entity. Exceptions Raised: JinxInvalidStateError -- More than one host had the specified hostname or mac address, or could not be found. """ hostname = hostname.lower() mac_address = mac_address.lower() servers = clusto.get_by_mac(mac_address) ipmi_hosts = clusto.get_entities(attrs=[{'subkey': 'ipmi_mac', 'value': mac_address}]) hosts = llclusto.get_by_hostname(hostname) if not servers and not ipmi_hosts: return HttpResponseInvalidState('Could not find any entities with MAC address: "%s".' % mac_address) try: clusto.begin_transaction() for host in hosts: for (port_type, port_num, ignore, ignore) in host.port_info_tuples: if host.get_hostname(port_type, port_num) == hostname: host.del_hostname(port_type, port_num) for server in servers: for (port_type, port_num, ignore, ignore) in server.port_info_tuples: if server.get_port_attr(port_type, port_num, "mac") == mac_address: server.set_hostname(hostname, port_type, port_num) for host in ipmi_hosts: ipmi = host.ipmi if ipmi[1] == mac_address: host.set_ipmi_info(hostname, ipmi[1]) clusto.commit() except: clusto.rollback_transaction() raise
def delete_si_image(request, si_hostname, image_name): """Deletes the PGI image from systemimager. Returns: None Arguments: si_hostname -- the systemimager hostname formatted as a string. image_name -- the image name formatted at a string. Exceptions Raised: JinxDataNotFoundError -- unable to find matching systemimager hostname or image_name. -- unable to find image on systemimager. JinxInvalidStateError -- image is still associated with hosts. -- more than one host was found matching the hostname. """ try: image = clusto.get_by_name(image_name) except LookupError: return HttpResponseNotFound("Image '%s' does not exist." % image_name) hosts = llclusto.get_by_hostname(si_hostname) if len(hosts) < 1: return HttpResponseNotFound("Systemimager hostname '%s' does not exist" % si_hostname) elif len(hosts) > 1: return HttpResponseInvalidState("Multiple hosts found matching '%s'" % si_hostname) host = hosts[0] # First, verify no host is using this as a current image hosts = image.get_hosts_associated_with() if len(hosts) != 0: hostnames = [host.hostname for host in hosts] return HttpResponseInvalidState( "Unable to delete image from SI host. Image '%s' currently in use by hosts: '%s'" % (image_name, ",".join(hostnames)) ) try: host.delete_stored_pgi_image(image) except LookupError: return HttpResponseNotFound( "Image '%s' is not marked as stored on systemimager '%s'." % (image_name, si_hostname) ) return
def _get_host(host_name): """Utility function to get a host by name. Exceptions Raised: JinxDataNotFoundError -- No host with the specified name exists. JinxInvalidRequestError -- The specified name refers to something that isn't a host. """ try: host = llclusto.get_by_hostname(host_name)[0] except IndexError: raise JinxDataNotFoundError("Host '%s' not found." % host_name) if not isinstance(host, LindenServer): raise JinxInvalidRequestError("%s is not a host." % host_name) return host
def get_host_state(request, hostname): """Gets the state of a host. Returns: The host's state, as a string. If the host has no state set, returns None. Arguments: hostname -- The name of the host whose state will be retrieved. Exceptions Raised: JinxDataNotFoundError -- A host with the specified hostname was not found. """ try: host = llclusto.get_by_hostname(hostname)[0] return host.state except IndexError: return HttpResponseNotFound("Host %s not found." % hostname)
def get_host_or_mac_object(request, hostname_or_mac): """ Returns an object for a hostname or a mac address... Arguments: hostname_or_mac -- The hostname or mac address of an entity. """ hosts = None if re.match(r'[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}', hostname_or_mac, re.I): hosts = clusto.get_by_mac(hostname_or_mac) if not hosts: hosts = llclusto.get_by_hostname(hostname_or_mac) if not hosts: return HttpResponseNotFound('No host was found with hostname or MAC address "%s".' % hostname_or_mac) elif len(hosts) > 1: return HttpResponse('More than one host found with hostname or MAC address "%s".' % hostname_or_mac, status=409) else: return hosts[0]
def get_log_events(request, hostname=None, user=None, event_type=None, start_timestamp=None, end_timestamp=None): """Returns a list of log events based on a number of parameters. Returns: A list of dictionaries, where each dictionary is a log event matching all of the parameters passed in. Arguments: hostname -- the hostname associated with the log event. user -- the user who triggered the event. event_type -- the name of the event type. start_timestamp -- the beginning datetime timestamp. All found log events will have a timestamp after this datetime. end_timestamp -- the end datetime timestamp. All found log event will have a timestamp before this datetime Exceptions Raised: JinxDataNotFoundError -- the hostname or the event_type could not be found JinxInvalidStateError -- more than one host was found matching the hostname """ log_events = [] host = None if hostname: host = llclusto.get_by_hostname(hostname) if len(host) < 1: return HttpResponseNotFound("No entity found for '%s'" % hostname) elif len(host) > 1: return HttpResponseInvalidState("Multiple entities found for '%s'" % hostname) else: host = host[0] if event_type: try: event_type = clusto.get_by_name(event_type) except LookupError, e: return HttpResponseNotFound("Event type '%s' does not exist" % event_type)
def set_host_state(request, hostname, state): """Sets the state of a host. Returns: None Arguments: hostname -- The name of the host whose state will be retrieved. state -- The state to set which to set the host. This state must already exist (see list_states()). Exceptions Raised: JinxDataNotFoundError -- A host with the specified hostname was not found. JinxInvalidStateError -- The specified state does not exist. Please see list_states() for a list of valid states. """ try: host = llclusto.get_by_hostname(hostname)[0] # Fetch the "State Change" LogEventType state_change = clusto.get_by_name("state change") old_state = host.state try: clusto.begin_transaction() if state is None: del host.state else: host.state = state host.add_log_event(user=request.META['REMOTE_USER'], event_type=state_change, old_state=old_state, new_state=state) clusto.commit() except: clusto.rollback_transaction() raise except IndexError: return HttpResponseNotFound("Host %s not found." % hostname) except ValueError: return HttpResponseInvalidState("State %s does not exist." % state)
Exceptions Raised: JinxDataNotFoundError -- the hostname or the event_type could not be found JinxInvalidStateError -- more than one host was found matching the hostname """ if event_type: try: event_type = clusto.get_by_name(event_type) except LookupError, e: return HttpResponseNotFound("Event type '%s' does not exist" % event_type) # Default to the user from the kerberos principal if user is None: user = request.META['REMOTE_USER'] source_entity = llclusto.get_by_hostname(hostname) if len(source_entity) < 1: return HttpResponseNotFound("No entity found for '%s'" % hostname) elif len(source_entity) > 1: return HttpResponseInvalidState("Multiple entities found for '%s'" % hostname) source_entity[0].add_log_event(user=user, event_type=event_type, timestamp=datetime.datetime.utcnow(), description=description, **kwargs) def add_log_event_type(request, event_type, description=None): """Adds a new log event type.