def node(*nodes): """Selects and configures a list of nodes. 'all' configures all nodes""" chef.build_node_data_bag() 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 lib.global_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 # Check whether another command was given in addition to "node:" 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 with settings(): execute(_node_runner) chef.remove_local_node_data_bag()
def node(*nodes): """Selects and configures a list of nodes. 'all' configures all nodes""" chef.build_node_data_bag() 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 lib.global_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 # Check whether another command was given in addition to "node:" 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 with settings(): execute(_node_runner) chef.remove_local_node_data_bag()
def test_attribute_merge_cookbook_default(self): """Should have the value found in recipe/attributes/default.rb""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode2.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('subversion' in data) self.assertTrue(data['subversion']['repo_name'] == 'repo')
def test_attribute_merge_environment_default(self): """Should have the value found in environment/ENV.json""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode1.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('subversion' in data) self.assertEqual(data['subversion']['user'], 'tom')
def test_attribute_merge_role_override(self): """Should have the value found in the roles override attributes""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode2.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('subversion' in data) self.assertEqual(data['subversion']['password'], 'role_override_pass')
def test_attribute_merge_cookbook_boolean(self): """Should have real boolean values for default cookbook attributes""" chef.build_node_data_bag() item_path = os.path.join( 'data_bags', 'node', 'testnode3_mydomain_com.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('vim' in data) self.assertTrue(data['vim']['sucks'] is True)
def test_attribute_merge_cookbook_boolean(self): """Should have real boolean values for default cookbook attributes""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode3_mydomain_com.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('vim' in data) self.assertTrue(data['vim']['sucks'] is True)
def test_attribute_merge_role_default(self): """Should have the value found in the roles default attributes""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode2.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('subversion' in data) self.assertEqual(data['subversion']['repo_server'], 'role_default_repo_server') self.assertTrue('other_attr' in data) self.assertEqual(data['other_attr']['other_key'], 'nada')
def test_attribute_merge_role_default(self): """Should have the value found in the roles default attributes""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode2.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('subversion' in data) self.assertEqual( data['subversion']['repo_server'], 'role_default_repo_server') self.assertTrue('other_attr' in data) self.assertEqual(data['other_attr']['other_key'], 'nada')
def build_node_data_bag(): """Tells LittleChef to build the node data bag""" current_dir = os.getcwd() os.chdir(KITCHEN_DIR) try: lib.get_recipes() # This builds metadata.json for all recipes chef.build_node_data_bag() except SystemExit as e: log.error(e) finally: os.chdir(current_dir) return True
def test_build_node_data_bag_nonalphanumeric(self): """Should create a node data bag when node name contains invalid chars """ chef.build_node_data_bag() # A node called testnode3.mydomain.com will have the data bag id # 'testnode3', because dots are not allowed. filename = 'testnode3_mydomain_com' nodename = filename.replace("_", ".") item_path = os.path.join('data_bags', 'node', filename + '.json') self.assertTrue(os.path.exists(item_path), "node file does not exist") with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('id' in data and data['id'] == filename) self.assertTrue('name' in data and data['name'] == nodename)
def test_attribute_merge_deep_dict(self): """Should deep-merge a dict when it is defined in two different places """ chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode2.json') with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('other_attr' in data) expected = { "deep_dict": { "deep_key1": "node_value1", "deep_key2": "role_value2" } } self.assertTrue(data['other_attr']['deep_dict'], expected)
def test_automatic_attributes(self): """Should add Chef's automatic attributes""" chef.build_node_data_bag() # Check node with single word fqdn testnode1_path = os.path.join('data_bags', 'node', 'testnode1.json') with open(testnode1_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('fqdn' in data and data['fqdn'] == 'testnode1') self.assertTrue('hostname' in data and data['hostname'] == 'testnode1') self.assertTrue('domain' in data and data['domain'] == '') # Check node with complex fqdn testnode3_path = os.path.join('data_bags', 'node', 'testnode3_mydomain_com.json') with open(testnode3_path, 'r') as f: print testnode3_path data = json.loads(f.read()) self.assertTrue('fqdn' in data and data['fqdn'] == 'testnode3.mydomain.com') self.assertTrue('hostname' in data and data['hostname'] == 'testnode3') self.assertTrue('domain' in data and data['domain'] == 'mydomain.com')
def test_automatic_attributes(self): """Should add Chef's automatic attributes""" chef.build_node_data_bag() # Check node with single word fqdn testnode1_path = os.path.join('data_bags', 'node', 'testnode1.json') with open(testnode1_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('fqdn' in data and data['fqdn'] == 'testnode1') self.assertTrue('hostname' in data and data['hostname'] == 'testnode1') self.assertTrue('domain' in data and data['domain'] == '') # Check node with complex fqdn testnode3_path = os.path.join( 'data_bags', 'node', 'testnode3_mydomain_com.json') with open(testnode3_path, 'r') as f: print testnode3_path data = json.loads(f.read()) self.assertTrue( 'fqdn' in data and data['fqdn'] == 'testnode3.mydomain.com') self.assertTrue('hostname' in data and data['hostname'] == 'testnode3') self.assertTrue('domain' in data and data['domain'] == 'mydomain.com')
def test_build_node_data_bag(self): """Should create a node data bag with one item per node""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode1.json') self.assertTrue(os.path.exists(item_path)) with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('id' in data and data['id'] == 'testnode1') self.assertTrue('name' in data and data['name'] == 'testnode1') self.assertTrue('recipes' in data and data['recipes'] == ['subversion']) self.assertTrue('recipes' in data and data['role'] == []) item_path = os.path.join('data_bags', 'node', 'testnode2.json') self.assertTrue(os.path.exists(item_path)) with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('id' in data and data['id'] == 'testnode2') self.assertTrue('recipes' in data) self.assertEqual(data['recipes'], [u'subversion', u'man']) self.assertTrue('recipes' in data) self.assertEqual(data['role'], [u'all_you_can_eat']) self.assertEqual(data['roles'], [u'base', u'all_you_can_eat'])
def test_build_node_data_bag(self): """Should create a node data bag with one item per node""" chef.build_node_data_bag() item_path = os.path.join('data_bags', 'node', 'testnode1.json') self.assertTrue(os.path.exists(item_path)) with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('id' in data and data['id'] == 'testnode1') self.assertTrue('name' in data and data['name'] == 'testnode1') self.assertTrue( 'recipes' in data and data['recipes'] == ['subversion']) self.assertTrue( 'recipes' in data and data['role'] == []) item_path = os.path.join('data_bags', 'node', 'testnode2.json') self.assertTrue(os.path.exists(item_path)) with open(item_path, 'r') as f: data = json.loads(f.read()) self.assertTrue('id' in data and data['id'] == 'testnode2') self.assertTrue('recipes' in data) self.assertEqual(data['recipes'], [u'subversion', u'man']) self.assertTrue('recipes' in data) self.assertEqual(data['role'], [u'all_you_can_eat']) self.assertEqual(data['roles'], [u'base', u'all_you_can_eat'])