Beispiel #1
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
Beispiel #2
0
def deploy_chef(gems="no", ask="yes", version="0.10",
    distro_type=None, distro=None, stop_client='yes'):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODE deploy_chef')
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort('Wrong Chef version specified. Valid versions are {0}'.format(
            ", ".join(chef_versions)))
    if distro_type is None and distro is None:
        distro_type, distro = solo.check_distro()
    elif distro_type is None or distro is None:
        abort('Must specify both or neither of distro_type and distro')
    if ask == "yes":
        message = '\nAre you sure you want to install Chef {0}'.format(version)
        message += ' at the node {0}'.format(env.host_string)
        if gems == "yes":
            message += ', using gems for "{0}"?'.format(distro)
        else:
            message += ', using "{0}" packages?'.format(distro)
        if not confirm(message):
            abort('Aborted by user')
    else:
        if gems == "yes":
            method = 'using gems for "{0}"'.format(distro)
        else:
            method = '{0} using "{1}" packages'.format(version, distro)
        print("Deploying Chef {0}...".format(method))

    if not __testing__:
        solo.install(distro_type, distro, gems, version, stop_client)
        solo.configure()
Beispiel #3
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
Beispiel #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'])
    # 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
Beispiel #5
0
def deploy_chef(gems="no", ask="yes", version="0.10",
    distro_type=None, distro=None, stop_client='yes'):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES deploy_chef')
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort('Wrong Chef version specified. Valid versions are {0}'.format(
            ", ".join(chef_versions)))
    if distro_type is None and distro is None:
        distro_type, distro = solo.check_distro()
    elif distro_type is None or distro is None:
        abort('Must specify both or neither of distro_type and distro')
    if ask == "yes":
        message = '\nAre you sure you want to install Chef {0}'.format(version)
        message += ' at the node {0}'.format(env.host_string)
        if gems == "yes":
            message += ', using gems for "{0}"?'.format(distro)
        else:
            message += ', using "{0}" packages?'.format(distro)
        if not confirm(message):
            abort('Aborted by user')
    else:
        if gems == "yes":
            method = 'using gems for "{0}"'.format(distro)
        else:
            method = '{0} using "{1}" packages'.format(version, distro)
        print("Deploying Chef {0}...".format(method))

    if not __testing__:
        solo.install(distro_type, distro, gems, version, stop_client)
        solo.configure()
Beispiel #6
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)
Beispiel #7
0
def _configure_node(configfile):
    """Exectutes chef-solo to apply roles and recipes to a node"""
    print "Uploading node.json..."
    remote_file = '/root/{0}'.format(configfile.split("/")[-1])
    # Ensure secure permissions
    put(configfile, remote_file, use_sudo=True, mode=400)
    sudo('chown root:root {0}'.format(remote_file)),
    sudo('mv {0} /etc/chef/node.json'.format(remote_file)),
    # Remove local temporary node file
    os.remove(configfile)
    # Always configure Chef Solo
    solo.configure()

    print "\n== Cooking ==\n"
    with settings(hide('warnings', 'running'), warn_only=True):
        output = sudo(
            'chef-solo -l {0} -j /etc/chef/node.json'.format(env.loglevel))
        if output.failed:
            if 'chef-solo: command not found' in output:
                print(
                    colors.red(
                        "\nFAILED: Chef Solo is not installed on this node"))
                print(
                    "Type 'cook nodes:{0} deploy_chef' to install it".format(
                        env.host))
                abort("")
            else:
                print(colors.red(
                    "\nFAILED: A problem occurred while executing chef-solo"))
                abort("")
        else:
            print(colors.green("\nSUCCESS: Node correctly configured"))
Beispiel #8
0
def _configure_node(configfile):
    """Exectutes chef-solo to apply roles and recipes to a node"""
    with hide('running'):
        print "Uploading node.json..."
        remote_file = '/root/{0}'.format(configfile.split("/")[-1])
        # Ensure secure permissions
        put(configfile, remote_file, use_sudo=True, mode=400)
        sudo('chown root:root {0}'.format(remote_file)),
        sudo('mv {0} /etc/chef/node.json'.format(remote_file)),
        # Remove local temporary node file
        os.remove(configfile)
        # Always configure Chef Solo
        solo.configure()
        print "\n== Cooking ==\n"
        with settings(hide('warnings'), warn_only=True):
            output = sudo(
                'chef-solo -l {0} -j /etc/chef/node.json'.format(env.loglevel))
            if output.failed:
                if 'chef-solo: command not found' in output:
                    print(
                        colors.red(
                            "\nFAILED: Chef Solo is not installed on this node"))
                    print(
                        "Type 'cook nodes:{0} deploy_chef' to install it".format(
                            env.host))
                    abort("")
                else:
                    print(colors.red(
                        "\nFAILED: A problem occurred while executing chef-solo"))
                    abort("")
            else:
                print(colors.green("\nSUCCESS: Node correctly configured"))
Beispiel #9
0
def deploy_chef(gems="no", ask="yes", version="0.9"):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort("no node specified\nUsage: cook node:MYNODE deploy_chef")
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort("Wrong Chef version specified. Valid versions are {0}".format(", ".join(chef_versions)))
    distro_type, distro = solo.check_distro()
    if ask == "yes":
        message = "\nAre you sure you want to install Chef"
        message += "at the node {0}".format(env.host_string)
        if gems == "yes":
            message += ', using gems for "{0}"?'.format(distro)
        else:
            message += ', using "{0}" packages?'.format(distro)
        if not confirm(message):
            abort("Aborted by user")
    else:
        if gems == "yes":
            method = ' using gems for "{0}"'.format(distro)
        else:
            method = ' {0} using "{1}" packages'.format(version, distro)
        print ("Deploying Chef {0}...".format(method))

    solo.install(distro_type, distro, gems, version)
    solo.configure()
Beispiel #10
0
def deploy_chef(gems="no", ask="yes", version="0.9"):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: cook node:MYNODE deploy_chef')
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort('Wrong Chef version specified. Valid versions are {0}'.format(
            ", ".join(chef_versions)))
    distro_type, distro = solo.check_distro()
    if ask == "yes":
        message = '\nAre you sure you want to install Chef'
        message += 'at the node {0}'.format(env.host_string)
        if gems == "yes":
            message += ', using gems for "{0}"?'.format(distro)
        else:
            message += ', using "{0}" packages?'.format(distro)
        if not confirm(message):
            abort('Aborted by user')
    else:
        if gems == "yes":
            method = ' using gems for "{0}"'.format(distro)
        else:
            method = ' {0} using "{1}" packages'.format(version, distro)
        print("Deploying Chef {0}...".format(method))

    solo.install(distro_type, distro, gems, version)
    solo.configure()
Beispiel #11
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
Beispiel #12
0
def deploy_chef(gems="no", ask="yes", version="0.10", distro_type=None,
                distro=None, platform=None, stop_client='yes', method=None):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES deploy_chef')
    deprecated_parameters = [distro_type, distro, platform]
    if any(param is not None for param in deprecated_parameters) or gems != 'no':
        print("DeprecationWarning: the parameters 'gems', distro_type',"
              " 'distro' and 'platform' will no longer be supported "
              "in future versions of LittleChef. Use 'method' instead")
    if distro_type is None and distro is None:
        distro_type, distro, platform = solo.check_distro()
    elif distro_type is None or distro is None:
        abort('Must specify both or neither of distro_type and distro')
    if method:
        if method not in ['omnibus', 'gentoo', 'pacman']:
            abort('Invalid omnibus method {0}. Supported methods are '
                  'omnibus, gentoo and pacman'.format(method))
        msg = "{0} using the {1} installer".format(version, method)
    else:
        if gems == "yes":
            msg = 'using gems for "{0}"'.format(distro)
        else:
            msg = '{0} using "{1}" packages'.format(version, distro)
    if method == 'omnibus' or ask == "no" or littlechef.noninteractive:
        print("Deploying Chef {0}...".format(msg))
    else:
        message = ('\nAre you sure you want to install Chef '
                   '{0} on node {1}?'.format(msg, env.host_string))
        if not confirm(message):
            abort('Aborted by user')

    _configure_fabric_for_platform(platform)

    if not __testing__:
        solo.install(distro_type, distro, gems, version, stop_client, method)
        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)
Beispiel #13
0
def deploy_chef(gems="no", ask="yes", version="0.10",
    distro_type=None, distro=None, platform=None, stop_client='yes'):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: fix node:MYNODES deploy_chef')
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort('Wrong Chef version specified. Valid versions are {0}'.format(
            ", ".join(chef_versions)))
    if distro_type is None and distro is None:
        distro_type, distro, platform = solo.check_distro()
    elif distro_type is None or distro is None:
        abort('Must specify both or neither of distro_type and distro')
    if ask == "yes":
        message = '\nAre you sure you want to install Chef {0}'.format(version)
        message += ' on node {0}'.format(env.host_string)
        if gems == "yes":
            message += ', using gems for "{0}"?'.format(distro)
        else:
            message += ', using "{0}" packages?'.format(distro)
        if not confirm(message):
            abort('Aborted by user')
    else:
        if gems == "yes":
            method = 'using gems for "{0}"'.format(distro)
        else:
            method = '{0} using "{1}" packages'.format(version, distro)
        print("Deploying Chef {0}...".format(method))

    _configure_fabric_for_platform(platform)

    if not __testing__:
        solo.install(distro_type, distro, gems, version, stop_client)
        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 json.JSONDecodeError:
                abort("Could not parse ohai's output"
                      ":\n  {0}".format(output))
            node = {"run_list": []}
            for prop in ["ipaddress", "platform", "platform_family",
                         "platform_version"]:
                if ohai[prop]:
                    node[prop] = ohai[prop]
            chef.save_config(node)
Beispiel #14
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.
    """
    with lib.credentials():
        # Get merged attributes
        current_node = _build_node_data_bag()
        # Always configure Chef Solo
        solo.configure(current_node)
        # Everything was configured alright, so save the node configuration
        filepath = save_config(node, _get_ipaddress(node))
        _synchronize_node(filepath)
        _remove_node_data_bag()
        _configure_node()
Beispiel #15
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.
    """
    with lib.credentials():
        # Get merged attributes
        current_node = _build_node_data_bag()
        # Always configure Chef Solo
        solo.configure(current_node)
        # Everything was configured alright, so save the node configuration
        filepath = save_config(node, _get_ipaddress(node))
        try:
            _synchronize_node(filepath)
            _configure_node()
        finally:
            _remove_local_node_data_bag()
            _node_cleanup()
Beispiel #16
0
def deploy_chef(gems="no", ask="yes", version="0.9"):
    """Install chef-solo on a node"""
    if not env.host_string:
        abort('no node specified\nUsage: cook node:MYNODE deploy_chef')
    chef_versions = ["0.9", "0.10"]
    if version not in chef_versions:
        abort('Wrong Chef version specified. Valid versions are {0}'.format(
            ", ".join(chef_versions)))
    distro_type, distro = solo.check_distro()
    message = '\nAre you sure you want to install Chef at the node {0}'.format(
        env.host_string)
    if gems == "yes":
        message += ', using gems for "{0}"?'.format(distro)
    else:
        message += ', using "{0}" packages?'.format(distro)
    if ask != "no" and not confirm(message):
        abort('Aborted by user')

    solo.install(distro_type, distro, gems, version)
    solo.configure()
Beispiel #17
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)
Beispiel #18
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.
    """
    # 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)
            # Execute Chef Solo
            _configure_node()
        finally:
            _remove_local_node_data_bag()
            _node_cleanup()
Beispiel #19
0
 def test_configure_bad_credentials(self, mock_exists):
     """Should return True when node has been synced"""
     mock_exists.side_effect = EOFError(
         '/usr/lib64/python2.6/getpass.py:83: GetPassWarning: '
         'Can not control echo on the terminal.')
     solo.configure()
Beispiel #20
0
 def test_configure_bad_credentials(self, mock_exists):
     """Should return True when node has been synced"""
     mock_exists.side_effect = EOFError(
         '/usr/lib64/python2.6/getpass.py:83: GetPassWarning: '
         'Can not control echo on the terminal.')
     solo.configure()