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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
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
Example #9
0
    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
Example #10
0
    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 testGetByHostname(self):
        d1 = TestLLClusto()
        d1.hostname = 'foo'

        s1 = llclusto.get_by_hostname('foo')

        self.assertEqual(len(s1), 1)
        self.assertEqual(s1[0], d1)
Example #13
0
    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)."
        )
Example #14
0
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
Example #15
0
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
Example #16
0
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
Example #17
0
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)
Example #18
0
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]
Example #19
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)
Example #20
0
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)
Example #21
0
    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.