Example #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)
Example #2
0
    def test_attribute_merge_cookbook_not_found(self):
        """Should print a warning when merging a node and a cookbook is not
        found

        """
        # Save new node with a non-existing cookbook assigned
        env.host_string = 'extranode'
        chef.save_config({"run_list": ["recipe[phantom_cookbook]"]})
        self.assertRaises(SystemExit, chef.build_node_data_bag)
Example #3
0
    def test_attribute_merge_cookbook_not_found(self):
        """Should print a warning when merging a node and a cookbook is not
        found

        """
        # Save new node with a non-existing cookbook assigned
        env.host_string = 'extranode'
        chef.save_config({"run_list": ["recipe[phantom_cookbook]"]})
        self.assertRaises(SystemExit, chef._build_node_data_bag)
Example #4
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)
Example #5
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)
Example #6
0
def execute(node):
    """Uses ohai to get virtualization information which is then saved to then
    node file

    """
    with hide('everything'):
        virt = json.loads(sudo('ohai virtualization'))
    if not len(virt) or virt[0][1] != "host":
        # It may work for virtualization solutions other than Xen
        print("This node is not a Xen host, doing nothing")
        return
    node['virtualization'] = {
        'role': 'host',
        'system': 'xen',
        'vms': [],
    }
    # VMs
    with hide('everything'):
        vm_list = sudo("xm list")
    for vm in vm_list.split("\n")[2:]:
        data = vm.split()
        if len(data) != 6:
            break
        node['virtualization']['vms'].append({
            'fqdn': data[0],
            'RAM': data[2],
            'cpus': data[3]
        })
    print("Found {0} VMs for this Xen host".format(
        len(node['virtualization']['vms'])))
    # Save node file and remove the returned temp file
    del node['name']
    os.remove(chef.save_config(node, True))
Example #7
0
def get_ips():
    """Ping all nodes and update their 'ipaddress' field"""
    import subprocess
    for node in lib.get_nodes():
        # For each node, ping the hostname
        env.host_string = node['name']
        proc = subprocess.Popen(['ping', '-c', '1', node['name']],
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        resp, error = proc.communicate()
        if not error:
            # Get lines from output and parse the first line to get the IP
            lines = resp.split("\n")
            # IP Address Regex http://www.regular-expressions.info/examples.html
            ip_matches = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', lines[0])
            ip = ip_matches[0] if ip_matches else None
            if not ip:
                print "Warning: could not get IP address from node {0}".format(
                    node['name'])
                continue
            print "Node {0} has IP {1}".format(node['name'], ip)
            # Update with the ipaddress field in the corresponding node.json
            del node['name']
            node['ipaddress'] = ip
            os.remove(chef.save_config(node, ip))
        else:
            print "Warning: could not resolve node {0}".format(node['name'])
Example #8
0
def execute(node):
  "Uses ohai to get cloud info and save to the node"

  with hide('everything'):
    ohai = json.loads(sudo('ohai'))
  if not len(ohai):
    print("Not a cloud node, skipping")
    return
  node['cloud'] = ohai['cloud']
  del node['name']
  os.remove(chef.save_config(node, True))
Example #9
0
def execute(node):
  "Uses ohai to get cloud info and save to the node"

  with hide('everything'):
    ohai = json.loads(sudo('ohai -d /etc/chef/ohai_plugins'))
  if not len(ohai):
    print("No network? This is wrong")
    return
  del(ohai['network']['interfaces'])
  node['network'] = ohai['network']
  del node['name']
  os.remove(chef.save_config(node, True))
Example #10
0
    def test_save_config(self):
        """Should create a tmp_testnode4.json and a nodes/testnode4.json config file

        """
        # Save a new node
        env.host_string = 'testnode4'
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        file_path = os.path.join('nodes', 'testnode4.json')
        self.assertTrue(os.path.exists(file_path))
        with open(file_path, 'r') as f:
            data = json.loads(f.read())
        self.assertEquals(data['run_list'], run_list)

        # It should't overwrite existing config files
        env.host_string = 'testnode1'  # This node exists
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        with open(os.path.join('nodes', 'testnode1.json'), 'r') as f:
            data = json.loads(f.read())
            # It should *NOT* have "base" assigned
            self.assertEquals(data['run_list'], ["recipe[subversion]"])
Example #11
0
    def test_save_config(self):
        """Should create a tmp_testnode4.json and a nodes/testnode4.json config file

        """
        # Save a new node
        env.host_string = 'testnode4'
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        file_path = os.path.join('nodes', 'testnode4.json')
        self.assertTrue(os.path.exists(file_path))
        with open(file_path, 'r') as f:
            data = json.loads(f.read())
        self.assertEquals(data['run_list'], run_list)

        # It should't overwrite existing config files
        env.host_string = 'testnode1'  # This node exists
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        with open(os.path.join('nodes', 'testnode1.json'), 'r') as f:
            data = json.loads(f.read())
            # It should *NOT* have "base" assigned
            self.assertEquals(data['run_list'], ["recipe[subversion]"])
Example #12
0
    def test_save_config(self):
        """Should create a tmp_extranode.json and a nodes/extranode.json config
        file

        """
        # Save a new node
        env.host_string = "extranode"
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        file_path = os.path.join("nodes", "extranode.json")
        self.assertTrue(os.path.exists(file_path))
        with open(file_path, "r") as f:
            data = json.loads(f.read())
        self.assertEquals(data["run_list"], run_list)

        # It should't overwrite existing config files
        env.host_string = "testnode1"  # This node exists
        run_list = ["role[base]"]
        chef.save_config({"run_list": run_list})
        with open(os.path.join("nodes", "testnode1.json"), "r") as f:
            data = json.loads(f.read())
            # It should *NOT* have "base" assigned
            self.assertEquals(data["run_list"], ["recipe[subversion]"])
Example #13
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)
Example #14
0
def execute(node):
    proc = subprocess.Popen(['ping', '-c', '1', node['name']],
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    resp, error = proc.communicate()
    if not error:
        # Split output into lines and parse the first line to get the IP
        ip = parse_ip(resp.split("\n")[0])
        if not ip:
            print "Warning: could not get IP address from node {0}".format(
                node['name'])
        print "Node {0} has IP {1}".format(node['name'], ip)
        # Update with the ipaddress field in the corresponding node.json
        node['ipaddress'] = ip
        os.remove(chef.save_config(node, ip))
    else:
        print "Warning: could not resolve node {0}".format(node['name'])
Example #15
0
def execute(node):
    proc = subprocess.Popen(['ping', '-c', '1', node['name']],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    resp, error = proc.communicate()
    if not error:
        # Split output into lines and parse the first line to get the IP
        ip = parse_ip(resp.split("\n")[0])
        if not ip:
            print "Warning: could not get IP address from node {0}".format(
                node['name'])
        print "Node {0} has IP {1}".format(node['name'], ip)
        # Update with the ipaddress field in the corresponding node.json
        node['ipaddress'] = ip
        os.remove(chef.save_config(node, ip))
    else:
        print "Warning: could not resolve node {0}".format(node['name'])
Example #16
0
def get_ips():
    """Ping all nodes and update their 'ipaddress' field"""
    import subprocess

    for node in lib.get_nodes():
        # For each node, ping the hostname
        env.host_string = node["name"]
        proc = subprocess.Popen(["ping", "-c", "1", node["name"]], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        resp, error = proc.communicate()
        if not error:
            # Get lines from output and parse the first line to get the IP
            lines = resp.split("\n")
            ip = lines[0].split()[2].lstrip("(").rstrip(")")
            if not ip:
                print "Warning: could not get IP address from node {0}".format(node["name"])
                continue
            print "Node {0} has IP {1}".format(node["name"], ip)
            # Update with the ipaddress field in the corresponding node.json
            del node["name"]
            node["ipaddress"] = ip
            os.remove(chef.save_config(node, ip))
        else:
            print "Warning: could not resolve node {0}".format(node["name"])
Example #17
0
def execute(node):
    """Uses ohai to get virtualization information which is then saved to then
    node file

    """
    with hide("everything"):
        virt = json.loads(sudo("ohai virtualization"))
    if not len(virt) or virt[0][1] != "host":
        # It may work for virtualization solutions other than Xen
        print("This node is not a Xen host, doing nothing")
        return
    node["virtualization"] = {"role": "host", "system": "xen", "vms": []}
    # VMs
    with hide("everything"):
        vm_list = sudo("xm list")
    for vm in vm_list.split("\n")[2:]:
        data = vm.split()
        if len(data) != 6:
            break
        node["virtualization"]["vms"].append({"fqdn": data[0], "RAM": data[2], "cpus": data[3]})
    print("Found {0} VMs for this Xen host".format(len(node["virtualization"]["vms"])))
    # Save node file and remove the returned temp file
    os.remove(chef.save_config(node, True))
Example #18
0
def execute(node):
    """
    Uses vmrunwrapper to get the IP fo the vm - assumes that the config file
    is all set up and it is either in ~/.vmrunwrapper.conf or the environment
    variable VMRUNWRAPPER_CONF points to it
    """
    wrapper = VmrunWrapper(get_config())
    ip = None

    try:
        ip = wrapper.update_ssh_config()
    except:
        pass

    if ip is None:
        print "Warning: could not get IP address from node {0}".format(
            node['name'])

    print "Node {0} has IP {1}".format(node['name'], ip)

    # Update with the ipaddress field in the corresponding node.json
    node['ipaddress'] = ip
    os.remove(chef.save_config(node, ip))
Example #19
0
def get_ips():
    """Ping all nodes and update their 'ipaddress' field"""
    import subprocess
    for node in lib.get_nodes():
        # For each node, ping the hostname
        env.host_string = node['name']
        proc = subprocess.Popen(['ping', '-c', '1', node['name']],
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        resp, error = proc.communicate()
        if not error:
            # Split output into lines and parse the first line to get the IP
            ip = lib.parse_ip(resp.split("\n")[0])
            if not ip:
                print "Warning: could not get IP address from node {0}".format(
                    node['name'])
                continue
            print "Node {0} has IP {1}".format(node['name'], ip)
            # Update with the ipaddress field in the corresponding node.json
            del node['name']
            node['ipaddress'] = ip
            os.remove(chef.save_config(node, ip))
        else:
            print "Warning: could not resolve node {0}".format(node['name'])
Example #20
0
 def test_attribute_merge_role_not_found(self):
     """Should print a warning when an assigned role if not found"""
     # Save new node with a non-existing cookbook assigned
     env.host_string = 'testnode4'
     chef.save_config({"run_list": ["role[phantom_role]"]})
     self.assertRaises(SystemExit, chef._build_node_data_bag)
Example #21
0
 def test_attribute_merge_role_not_found(self):
     """Should print a warning when an assigned role if not found"""
     # Save new node with a non-existing cookbook assigned
     env.host_string = 'testnode4'
     chef.save_config({"run_list": ["role[phantom_role]"]})
     self.assertRaises(SystemExit, chef._build_node_data_bag)
Example #22
0
def execute(node):
  node['run_list'] = ["role[base]"]
  del node['name']
  os.remove(chef.save_config(node, True))