Example #1
0
def update_new_cluster_member_status(bus, cluster, *hosts):
    """
    Call this helper function when adding new hosts to a cluster.  If
    applicable, it will register each host with the cluster's container
    manager.  Then it will update the host status accordingly and save
    the model(s) to permanent storage.

    :param bus: Bus instance
    :type bus: commissaire_http.bus.Bus
    :param cluster: A Cluster model instance
    :type cluster: commissaire.models.Cluster
    :param hosts: Tuple of Host model instances
    :type hosts: (commissaire.models.Host, ...)
    """
    for host in hosts:
        try:
            host.status = C.HOST_STATUS_DISASSOCIATED
            if cluster.container_manager:
                bus.request('container.register_node',
                            params=[cluster.container_manager, host.address])
                host.status = C.HOST_STATUS_ACTIVE
        except Exception as error:
            LOGGER.warn('Unable to register %s to container manager "%s": %s',
                        host.address, cluster.container_manager, error.args[0])
            raise error

    # Save the updated host models.
    bus.storage.save_many(hosts)
Example #2
0
def _does_cluster_exist(bus, cluster_name):
    """
    Shorthand to check and see if a cluster exists. If it does, return the
    message response data.

    :param bus: Bus instance.
    :type bus: commissaire_http.bus.Bus
    :param cluster_name: The name of the Cluster to look up.
    :type cluster_name: str
    :returns: The found Cluster instance or None
    :rtype: mixed
    """
    LOGGER.debug('Checking on cluster "{}"'.format(cluster_name))
    try:
        cluster = bus.storage.get_cluster(cluster_name)
        LOGGER.debug('Found cluster: "{}"'.format(cluster))
        return cluster
    except _bus.StorageLookupError as error:
        LOGGER.warn(
            'create_host could not find cluster "{}"'.format(cluster_name))
        return None
Example #3
0
def _does_cluster_exist(bus, cluster_name):
    """
    Shorthand to check and see if a cluster exists. If it does, return the
    message response data.

    :param bus: Bus instance.
    :type bus: commissaire_http.bus.Bus
    :param cluster_name: The name of the Cluster to look up.
    :type cluster_name: str
    :returns: The found Cluster instance or None
    :rtype: mixed
    """
    LOGGER.debug('Checking on cluster "{}"'.format(cluster_name))
    try:
        cluster = bus.request('storage.get', params=[
            'Cluster', {'name': cluster_name}, True])
        LOGGER.debug('Found cluster: "{}"'.format(cluster))
        return models.Cluster.new(**cluster['result'])
    except _bus.RemoteProcedureCallError as error:
        LOGGER.warn(
            'create_host could not find cluster "{}"'.format(cluster_name))
        LOGGER.debug('Error: {}: "{}"'.format(type(error), error))
Example #4
0
def get_host_status(message, bus):
    """
    Gets the status of an exisiting host.

    :param message: jsonrpc message structure.
    :type message: dict
    :param bus: Bus instance.
    :type bus: commissaire_http.bus.Bus
    :returns: A jsonrpc structure.
    :rtype: dict
    """
    try:
        host_response = bus.request(
            'storage.get',
            params=['Host', {
                'address': message['params']['address']
            }])
        host = models.Host.new(**host_response['result'])
        status = models.HostStatus.new(
            host={
                'last_check': host.last_check,
                'status': host.status,
            },
            # TODO: Update when we add other types.
            type=C.CLUSTER_TYPE_HOST)

        LOGGER.debug('Status for host "{0}": "{1}"'.format(
            host.address, status.to_json()))

        return create_response(message['id'], status.to_dict())
    except _bus.RemoteProcedureCallError as error:
        LOGGER.warn('Could not retrieve host "{}". {}: {}'.format(
            message['params']['address'], type(error), error))
        return return_error(message, error, JSONRPC_ERRORS['NOT_FOUND'])
    except Exception as error:
        LOGGER.debug('Host Status exception caught for {0}: {1}:{2}'.format(
            host.address, type(error), error))
        return return_error(message, error, JSONRPC_ERRORS['INTERNAL_ERROR'])
Example #5
0
def create_host(message, bus):
    """
    Creates a new host.

    :param message: jsonrpc message structure.
    :type message: dict
    :param bus: Bus instance.
    :type bus: commissaire_http.bus.Bus
    :returns: A jsonrpc structure.
    :rtype: dict
    """
    LOGGER.debug('create_host params: "{}"'.format(message['params']))
    try:
        address = message['params']['address']
    except KeyError:
        return return_error(
            message, '"address" must be given in the url or in the PUT body',
            JSONRPC_ERRORS['INVALID_PARAMETERS'])
    try:
        host = bus.request('storage.get', params=[
            'Host', {'address': address}, True])
        LOGGER.debug('Host "{}" already exisits.'.format(address))

        # Verify the keys match
        if (host['result']['ssh_priv_key'] !=
                message['params'].get('ssh_priv_key', '')):
            return return_error(
                message, 'Host already exists', JSONRPC_ERRORS['CONFLICT'])

        # Verify the cluster exists and it's in the cluster
        if message['params'].get('cluster'):
            cluster = _does_cluster_exist(bus, message['params']['cluster'])
            if not cluster:
                return return_error(
                    message, 'Cluster does not exist',
                    JSONRPC_ERRORS['INVALID_PARAMETERS'])
            # Verify the host is in the cluster
            if address not in cluster.hostset:
                LOGGER.debug('Host "{}" is not in cluster "{}"'.format(
                    address, message['params']['cluster']))
                return return_error(
                    message, 'Host not in cluster', JSONRPC_ERRORS['CONFLICT'])

        # Return out now. No more processing needed.
        return create_response(
            message['id'], models.Host.new(**host['result']).to_dict())

    except _bus.RemoteProcedureCallError as error:
        LOGGER.debug('Brand new host "{}" being created.'.format(
            message['params']['address']))

    if message['params'].get('cluster'):
        # Verify the cluster existence and add the host to it
        cluster_name = message['params']['cluster']
        cluster = _does_cluster_exist(bus, message['params']['cluster'])
        if not cluster:
            LOGGER.warn(
                'create_host could not find cluster "{}" for the creation '
                'of new host "{}"'.format(cluster_name, address))
            return return_error(
                message,
                'Cluster does not exist',
                JSONRPC_ERRORS['INVALID_PARAMETERS'])

        LOGGER.debug('Found cluster. Data: "{}"'.format(cluster))
        if address not in cluster.hostset:
            cluster.hostset.append(address)
            bus.request('storage.save', params=[
                'Cluster', cluster.to_dict(True)])

    try:
        # TODO: pass this off to the bootstrap process
        host = models.Host.new(**message['params'])
        host._validate()
        bus.request(
            'storage.save', params=[
                'Host', host.to_dict(True)])
        return create_response(message['id'], host.to_dict())
    except models.ValidationError as error:
        return return_error(message, error, JSONRPC_ERRORS['INVALID_REQUEST'])