Exemplo n.º 1
0
def deploy_chef(ask="yes", version="11"):
    """Install chef-solo on a node"""
    env.host_string = lib.get_env_host_string()
    if ask == "no" or littlechef.noninteractive:
        print("Deploying Chef using omnibus installer version: ...".format(version))
    else:
        message = ('\nAre you sure you want to install Chef version:'
                   '{0} on node {1}?'.format(version, env.host_string))
        if not confirm(message):
            abort('Aborted by user')

    lib.print_header("Configuring Chef Solo on {0}".format(env.host_string))

    if not __testing__:
        solo.install(version)
        solo.configure()

        # Build a basic node file if there isn't one already
        # with some properties from ohai
        with settings(hide('stdout'), warn_only=True):
            output = sudo('ohai -l warn')
        if output.succeeded:
            try:
                ohai = json.loads(output)
            except ValueError:
                abort("Could not parse ohai's output"
                      ":\n  {0}".format(output))
            node = {"run_list": []}
            for attribute in ["ipaddress", "platform", "platform_family",
                              "platform_version"]:
                if ohai.get(attribute):
                    node[attribute] = ohai[attribute]
            chef.save_config(node)
Exemplo n.º 2
0
def sync_node(node, on_sync=None):
    """Builds, synchronizes and configures a node.
    It also injects the ipaddress to the node's config file if not already
    existent.

    """
    if node.get('dummy') or 'dummy' in node.get('tags', []):
        lib.print_header("Skipping dummy: {0}".format(env.host))
        return False
    current_node = lib.get_node(node['name'])
    # Always configure Chef Solo
    solo.configure(current_node)
    ipaddress = _get_ipaddress(node)
    # Everything was configured alright, so save the node configuration
    # This is done without credentials, so that we keep the node name used
    # by the user and not the hostname or IP translated by .ssh/config
    filepath = save_config(node, ipaddress)
    try:
        # Synchronize the kitchen directory
        _synchronize_node(filepath, node)
        if on_sync:
            on_sync()
        # Execute Chef Solo
        _configure_node()
    finally:
        _node_cleanup()
    return True
Exemplo n.º 3
0
def _node_runner(node_data=None):
    """This is only used by node so that we can execute in parallel"""
    env.host_string = lib.get_env_host_string()
    if node_data:
        node = node_data
    else:
        node = lib.get_node(env.host_string)

    _configure_fabric_for_platform(node.get("platform"))

    if node.get("gateway"):
        gateway = node.get("gateway")
    else:
        gateway = env.gateway

    if node.get("http_proxy"):
        http_proxy = node.get("http_proxy")
    else:
        http_proxy = env.http_proxy

    if node.get("https_proxy"):
        https_proxy = node.get("https_proxy")
    else:
        https_proxy = env.https_proxy

    with settings(https_proxy=https_proxy, http_proxy=http_proxy, gateway=gateway):
        if __testing__:
            print "TEST: would now configure {0}".format(env.host_string)
        else:
            lib.print_header("Configuring {0}".format(env.host_string))
            if env.autodeploy_chef and not chef.chef_test():
                deploy_chef(ask="no")
            chef.sync_node(node)
Exemplo n.º 4
0
def sync_node(node):
    """Builds, synchronizes and configures a node.
    It also injects the ipaddress to the node's config file if not already
    existent.

    """
    if node.get('dummy') or 'dummy' in node.get('tags', []):
        lib.print_header("Skipping dummy: {0}".format(env.host))
        return False
    current_node = lib.get_node(node['name'])
    # Check if node locked
    if solo.node_locked(current_node):
        content = json.loads(solo.get_lock_info(current_node))
        print colors.yellow("Skipping node {0}.\nLocked by {1}.\nReason: {2}".format(current_node['host_name'], content['author'], content['reason']))
        return False
    # Always configure Chef Solo
    solo.configure(current_node)
    ipaddress = _get_ipaddress(node)
    # Everything was configured alright, so save the node configuration
    # This is done without credentials, so that we keep the node name used
    # by the user and not the hostname or IP translated by .ssh/config
    filepath = save_config(node, ipaddress)
    try:
        # Synchronize the kitchen directory
        _synchronize_node(filepath, node)
        # Execute Chef Solo
        _configure_node(node)
    finally:
        _node_cleanup()
    return True
Exemplo n.º 5
0
def sync_node(node):
    """Builds, synchronizes and configures a node.
    It also injects the ipaddress to the node's config file if not already
    existent.
    """
    if node.get("dummy") or "dummy" in node.get("tags", []):
        lib.print_header("Skipping dummy: {0}".format(env.host))
        return False
    # Get merged attributes
    current_node = _build_node_data_bag()
    with lib.credentials():
        # Always configure Chef Solo
        solo.configure(current_node)
        ipaddress = _get_ipaddress(node)
    # Everything was configured alright, so save the node configuration
    # This is done without credentials, so that we keep the node name used
    # by the user and not the hostname or IP translated by .ssh/config
    filepath = save_config(node, ipaddress)
    with lib.credentials():
        try:
            # Synchronize the kitchen directory
            _synchronize_node(filepath, node)
            # Execute Chef Solo
            _configure_node()
        finally:
            _remove_local_node_data_bag()
            _node_cleanup()
    return True
Exemplo n.º 6
0
def sync_node(node):
    """Builds, synchronizes and configures a node.
    It also injects the ipaddress to the node's config file if not already
    existent.

    """
    if node.get('dummy') or 'dummy' in node.get('tags', []):
        lib.print_header("Skipping dummy: {0}".format(env.host))
        return False
    current_node = lib.get_node(node['name'])
    # Always configure Chef Solo
    solo.configure(current_node)
    ipaddress = _get_ipaddress(node)
    # Everything was configured alright, so save the node configuration
    # This is done without credentials, so that we keep the node name used
    # by the user and not the hostname or IP translated by .ssh/config
    filepath = save_config(node, ipaddress)
    try:
        # Synchronize the kitchen directory
        _synchronize_node(filepath, node)
        # Execute Chef Solo
        _configure_node()
    finally:
        _node_cleanup()
    return True
Exemplo n.º 7
0
def node(*nodes):
    """Selects and configures a list of nodes. 'all' configures all nodes"""
    if not len(nodes) or nodes[0] == '':
        abort('No node was given')
    elif nodes[0] == 'all':
        # Fetch all nodes and add them to env.hosts
        for node in lib.get_nodes():
            env.hosts.append(node['name'])
        if not len(env.hosts):
            abort('No nodes found in /nodes/')
    else:
        # A list of nodes was given
        env.hosts = nodes
    env.all_hosts = list(env.hosts)

    # Check whether another command was given in addition to "node:"
    execute = True
    if 'node:' not in sys.argv[-1]:
        execute = False
    # If user didn't type recipe:X, role:Y or deploy_chef, just run configure
    if execute:
        for hostname in env.hosts:
            env.host = hostname
            env.host_string = hostname
            lib.print_header("Configuring {0}".format(env.host))
            # Read node data and configure node
            node = lib.get_node(env.host)
            chef.sync_node(node)
Exemplo n.º 8
0
def _node_runner():
    """This is only used by node so that we can execute in parallel"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES recipe:MYRECIPE')
    if '@' in env.host_string:
        env.user = env.host_string.split('@')[0]
    node = lib.get_node(env.host_string)
    if __testing__:
        print "TEST: would now configure {0}".format(env.host_string)
    else:
        lib.print_header("Configuring {0}".format(env.host_string))
        chef.sync_node(node)
Exemplo n.º 9
0
def _node_runner():
    """This is only used by node so that we can execute in parallel"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES recipe:MYRECIPE')
    if '@' in env.host_string:
        env.user = env.host_string.split('@')[0]
    node = lib.get_node(env.host_string)
    if __testing__:
        print "TEST: would now configure {0}".format(env.host_string)
    else:
        lib.print_header("Configuring {0}".format(env.host_string))
        chef.sync_node(node)
Exemplo n.º 10
0
def _node_runner():
    """This is only used by node so that we can execute in parallel"""
    env.host_string = lib.get_env_host_string()
    node = lib.get_node(env.host_string)

    _configure_fabric_for_platform(node.get("platform"))

    if __testing__:
        print "TEST: would now configure {0}".format(env.host_string)
    else:
        lib.print_header("Configuring {0}".format(env.host_string))
        chef.sync_node(node)
Exemplo n.º 11
0
def configure():
    """Configure node using existing config file"""
    # Check that a node has been selected
    if not env.host_string:
        msg = "no node specified\n"
        msg += "Usage:\n  cook node:MYNODE configure"
        msg += "\n  cook node:all configure"
        abort(msg)
    lib.print_header("Configuring {0}".format(env.host_string))

    # Read node data and configure node
    node = lib.get_node(env.host_string)
    chef.sync_node(node)
Exemplo n.º 12
0
def configure():
    """Configure node using existing config file"""
    # Check that a node has been selected
    if not env.host_string:
        msg = 'no node specified\n'
        msg += 'Usage:\n  cook node:MYNODE configure'
        msg += '\n  cook node:all configure'
        abort(msg)
    lib.print_header("Configuring {0}".format(env.host_string))

    # Read node data and configure node
    node = lib.get_node(env.host_string)
    chef.sync_node(node)
Exemplo n.º 13
0
def plugin(name):
    """Executes the selected plugin
    Plugins are expected to be found in the kitchen's 'plugins' directory

    """
    env.host_string = lib.get_env_host_string()
    plug = lib.import_plugin(name)
    lib.print_header("Executing plugin '{0}' on "
                     "{1}".format(name, env.host_string))
    node = lib.get_node(env.host_string)
    if node == {'run_list': []}:
        node['name'] = env.host_string
    plug.execute(node)
    print("Finished executing plugin")
Exemplo n.º 14
0
def _node_runner():
    """This is only used by node so that we can execute in parallel"""
    env.host_string = lib.get_env_host_string()
    node = lib.get_node(env.host_string)

    _configure_fabric_for_platform(node.get("platform"))

    if __testing__:
        print "TEST: would now configure {0}".format(env.host_string)
    else:
        lib.print_header("Configuring {0}".format(env.host_string))
        if env.autodeploy_chef and not chef.chef_test():
            deploy_chef(ask="no")
        chef.sync_node(node)
Exemplo n.º 15
0
def plugin(name):
    """Executes the selected plugin
    Plugins are expected to be found in the kitchen's 'plugins' directory

    """
    env.host_string = lib.get_env_host_string()
    plug = lib.import_plugin(name)
    lib.print_header("Executing plugin '{0}' on "
                     "{1}".format(name, env.host_string))
    node = lib.get_node(env.host_string)
    if node == {'run_list': []}:
        node['name'] = env.host_string
    plug.execute(node)
    print("Finished executing plugin")
Exemplo n.º 16
0
def role(role):
    """Apply the given role to a node
    Sets the run_list to the given role
    If no nodes/hostname.json file exists, it creates one
    """
    # Check that a node has been selected
    if not env.host_string:
        abort("no node specified\nUsage: cook node:MYNODE role:MYROLE")
    lib.print_header("Applying role '{0}' to node {1}".format(role, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["role[{0}]".format(role)]
    chef.sync_node(data)
Exemplo n.º 17
0
def plugin(name):
    """Executes the selected plugin
    Plugins are expected to be found in the kitchen's 'plugins' directory

    """
    if not env.host_string:
        abort('No node specified\nUsage: fix node:MYNODES plugin:MYPLUGIN')
    plug = lib.import_plugin(name)
    lib.print_header("Executing plugin '{0}' on "
                     "{1}".format(name, env.host_string))
    node = lib.get_node(env.host_string)
    if node == {'run_list': []}:
        node['name'] = env.host_string
    plug.execute(node)
    print("Finished executing plugin")
Exemplo n.º 18
0
def plugin(name):
    """Executes the selected plugin
    Plugins are expected to be found in the kitchen's 'plugins' directory

    """
    if not env.host_string:
        abort('No node specified\nUsage: fix node:MYNODES plugin:MYPLUGIN')
    plug = lib.import_plugin(name)
    lib.print_header("Executing plugin '{0}' on "
                     "{1}".format(name, env.host_string))
    node = lib.get_node(env.host_string)
    if node == {'run_list': []}:
        node['name'] = env.host_string
    plug.execute(node)
    print("Finished executing plugin")
Exemplo n.º 19
0
def role(role):
    """Apply the given role to a node
    Sets the run_list to the given role
    If no nodes/hostname.json file exists, it creates one
    """
    # Check that a node has been selected
    if not env.host_string:
        abort('no node specified\nUsage: cook node:MYNODE role:MYROLE')
    lib.print_header("Applying role '{0}' to node {1}".format(
        role, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["role[{0}]".format(role)]
    chef.sync_node(data)
Exemplo n.º 20
0
def role(role):
    """Apply the given role to a node
    Sets the run_list to the given role
    If no nodes/hostname.json file exists, it creates one

    """
    env.host_string = lib.get_env_host_string()
    lib.print_header(
        "Applying role '{0}' to {1}".format(role, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["role[{0}]".format(role)]
    if not __testing__:
        chef.sync_node(data)
Exemplo n.º 21
0
def recipe(recipe):
    """Apply the given recipe to a node
    Sets the run_list to the given recipe
    If no nodes/hostname.json file exists, it creates one
    """
    # Check that a node has been selected
    if not env.host_string:
        abort("no node specified\nUsage: fix node:MYNODE recipe:MYRECIPE")
    lib.print_header("Applying recipe '{0}' on node {1}".format(recipe, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["recipe[{0}]".format(recipe)]
    if not __testing__:
        chef.sync_node(data)
Exemplo n.º 22
0
def recipe(recipe):
    """Apply the given recipe to a node
    Sets the run_list to the given recipe
    If no nodes/hostname.json file exists, it creates one

    """
    env.host_string = lib.get_env_host_string()

    # Create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["recipe[{0}]".format(recipe)]

    lib.print_header(
        "Applying recipe '{0}' on node {1}".format(recipe, env.host_string))

    _node_runner(node_data=data)
Exemplo n.º 23
0
def recipe(recipe):
    """Apply the given recipe to a node
    Sets the run_list to the given recipe
    If no nodes/hostname.json file exists, it creates one

    """
    env.host_string = lib.get_env_host_string()
    lib.print_header(
        "Applying recipe '{0}' on node {1}".format(recipe, env.host_string))

    # Create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["recipe[{0}]".format(recipe)]
    if not __testing__:
        if env.autodeploy_chef and not chef.chef_test():
            deploy_chef(ask="no")
        chef.sync_node(data)
Exemplo n.º 24
0
def role(role):
    """Apply the given role to a node
    Sets the run_list to the given role
    If no nodes/hostname.json file exists, it creates one

    """
    env.host_string = lib.get_env_host_string()
    lib.print_header("Applying role '{0}' to {1}".format(
        role, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["role[{0}]".format(role)]
    if not __testing__:
        if env.autodeploy_chef and not chef.chef_test():
            deploy_chef(ask="no")
        chef.sync_node(data)
Exemplo n.º 25
0
def recipe(recipe):
    """Apply the given recipe to a node
    Sets the run_list to the given recipe
    If no nodes/hostname.json file exists, it creates one

    """
    # Check that a node has been selected
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES recipe:MYRECIPE')
    lib.print_header("Applying recipe '{0}' on node {1}".format(
        recipe, env.host_string))

    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data["run_list"] = ["recipe[{0}]".format(recipe)]
    if not __testing__:
        chef.sync_node(data)
Exemplo n.º 26
0
def node(*nodes):
    """Selects and configures a list of nodes. 'all' configures all nodes"""
    if not len(nodes) or nodes[0] == '':
        abort('No node was given')
    elif nodes[0] == 'all':
        # Fetch all nodes and add them to env.hosts
        for node in lib.get_nodes(env.chef_environment):
            env.hosts.append(node['name'])
        if not len(env.hosts):
            abort('No nodes found in /nodes/')
        message = "Are you sure you want to configure all nodes ({0})".format(
            len(env.hosts))
        if env.chef_environment:
            message += " in the {0} environment".format(env.chef_environment)
        message += "?"
        if not __testing__:
            if not confirm(message):
                abort('Aborted by user')
    else:
        # A list of nodes was given
        env.hosts = list(nodes)
    env.all_hosts = list(env.hosts)  # Shouldn't be needed
    if len(env.hosts) > 1:
        print "Configuring nodes: {0}...".format(", ".join(env.hosts))

    # Check whether another command was given in addition to "node:"
    execute = True
    if not(littlechef.__cooking__ and
            'node:' not in sys.argv[-1] and
            'nodes_with_role:' not in sys.argv[-1]):
        # If user didn't type recipe:X, role:Y or deploy_chef,
        # configure the nodes
        for hostname in env.hosts:
            env.host = hostname
            env.host_string = hostname
            node = lib.get_node(env.host)
            if node.get('dummy'):
                lib.print_header("Skipping dummy: {0}".format(env.host))
            else:
                lib.print_header("Configuring {0}".format(env.host))
                if __testing__:
                    print "TEST: would now configure {0}".format(env.host)
                else:
                    chef.sync_node(node)
Exemplo n.º 27
0
def roles(*role_list, **kwargs):
    """Apply the given roles to a node
    Sets the run_list to the given roles
    If no nodes/hostname.json file exists, it creates one

    """
    env.host_string = lib.get_env_host_string()
    lib.print_header(
        "Applying roles '{0}' to {1}".format(role_list, env.host_string))

    override_data = kwargs.get('data', {})
    on_sync = kwargs.get('on_sync', None)
    # Now create configuration and sync node
    data = lib.get_node(env.host_string)
    data.update(override_data)
    data["run_list"] = ["role[{0}]".format(x) for x in role_list]
    if not __testing__:
        if env.autodeploy_chef and not chef.chef_test():
            deploy_chef(ask="no")
        chef.sync_node(data, on_sync)
Exemplo n.º 28
0
def node(*nodes):
    """Selects and configures a list of nodes. 'all' configures all nodes"""
    if not len(nodes) or nodes[0] == '':
        abort('No node was given')
    elif nodes[0] == 'all':
        # Fetch all nodes and add them to env.hosts
        for node in lib.get_nodes(env.chef_environment):
            env.hosts.append(node['name'])
        if not len(env.hosts):
            abort('No nodes found in /nodes/')
        message = "Are you sure you want to configure all nodes ({0})".format(
            len(env.hosts))
        if env.chef_environment:
            message += " in the {0} environment".format(env.chef_environment)
        message += "?"
        if not __testing__:
            if not confirm(message):
                abort('Aborted by user')
    else:
        # A list of nodes was given
        env.hosts = list(nodes)
    env.all_hosts = list(env.hosts)  # Shouldn't be needed
    if len(env.hosts) > 1:
        print "Configuring nodes: {0}...".format(", ".join(env.hosts))

    # Check whether another command was given in addition to "node:"
    execute = True
    if not (littlechef.__cooking__ and 'node:' not in sys.argv[-1]
            and 'nodes_with_role:' not in sys.argv[-1]):
        # If user didn't type recipe:X, role:Y or deploy_chef,
        # configure the nodes
        for hostname in env.hosts:
            env.host = hostname
            env.host_string = hostname
            node = lib.get_node(env.host)
            lib.print_header("Configuring {0}".format(env.host))
            if __testing__:
                print "TEST: would now configure {0}".format(env.host)
            else:
                chef.sync_node(node)
Exemplo n.º 29
0
def node(*nodes):
    """Selects and configures a list of nodes. 'all' configures all nodes"""
    if not len(nodes) or nodes[0] == "":
        abort("No node was given")
    elif nodes[0] == "all":
        # Fetch all nodes and add them to env.hosts
        for node in lib.get_nodes():
            if env.chef_environment is None or node.get("chef_environment") == env.chef_environment:
                env.hosts.append(node["name"])
        if not len(env.hosts):
            abort("No nodes found in /nodes/")
        message = "Are you sure you want to configure all nodes ({0})".format(len(env.hosts))
        if env.chef_environment:
            message += " in the {0} environment".format(env.chef_environment)
        message += "?"
        if not __testing__:
            if not confirm(message):
                abort("Aborted by user")
    else:
        # A list of nodes was given
        env.hosts = list(nodes)
    env.all_hosts = list(env.hosts)  # Shouldn't be needed
    if len(env.hosts) > 1:
        print "Configuring nodes: {0}...".format(", ".join(env.hosts))

    # Check whether another command was given in addition to "node:"
    execute = True
    if littlechef.__cooking__ and "node:" not in sys.argv[-1] and "nodes_with_role:" not in sys.argv[-1]:
        execute = False
    # If user didn't type recipe:X, role:Y or deploy_chef, just run configure
    if execute:
        for hostname in env.hosts:
            env.host = hostname
            env.host_string = hostname
            lib.print_header("Configuring {0}".format(env.host))
            # Read node data and configure node
            node = lib.get_node(env.host)
            if not __testing__:
                chef.sync_node(node)
Exemplo n.º 30
0
def deploy_chef(ask="yes", version="13.12.14"):
    """Install chef-solo on a node"""
    env.host_string = lib.get_env_host_string()
    if ask == "no" or littlechef.noninteractive:
        print("Deploying Chef using omnibus installer version: ...".format(
            version))
    else:
        message = ('\nAre you sure you want to install Chef version:'
                   '{0} on node {1}?'.format(version, env.host_string))
        if not confirm(message):
            abort('Aborted by user')

    lib.print_header("Configuring Chef Solo on {0}".format(env.host_string))

    if not __testing__:
        solo.install(version)
        solo.configure()

        # Build a basic node file if there isn't one already
        # with some properties from ohai
        with settings(hide('stdout'), warn_only=True):
            output = sudo('ohai -l warn')
        if output.succeeded:
            try:
                ohai = json.loads(output)
            except ValueError:
                abort("Could not parse ohai's output"
                      ":\n  {0}".format(output))
            node = {"run_list": []}
            for attribute in [
                    "ipaddress", "platform", "platform_family",
                    "platform_version"
            ]:
                if ohai.get(attribute):
                    node[attribute] = ohai[attribute]
            chef.save_config(node)