Create a gist now

Instantly share code, notes, and snippets.

@riltsken / Secret
Created Nov 21, 2014

What would you like to do?
littlechef-rackspace plugins ran after node is active
import os
import json
import httplib
import re
from fabric.api import sudo, hide
from littlechef import chef, runner
def get_interface_type(ip):
if ip.startswith('192.168'):
return "private"
elif ip.startswith('10.'):
return "servicenet"
return "public"
def get_environment(node_name):
if node_name.startswith('ord1'):
return 'production'
environments = (
('dev', 'dev'),
('test', 'test'),
('staging', 'staging'),
('preview', 'preprod'),
('preprod', 'preprod'),
('prod', 'production'),
for label, env in environments:
if label in node_name:
return env
return "unknown"
def execute(node):
Bootstrap a node with LittleChef:
* save network/cloud attributes
with hide('everything'):
result = sudo('ohai -l fatal')
# strip stuff before the first {, sometimes ohai gives a warning
result = result[result.find("{"):]
ohai = json.loads(result)
network_types = {}
network = ohai['network']
# Sort the interfaces alphabetically
sorted_interfaces = []
for iface in sorted(ohai['network']['interfaces']):
sorted_interfaces.append((iface, ohai['network']['interfaces'][iface]))
for iface, iface_dict in sorted_interfaces:
if iface.startswith('eth'):
addrs = iface_dict['addresses']
for ip in addrs:
if addrs[ip]['family'] == 'inet':
# Determine the interface type based on the ip address
interface_type = get_interface_type(ip)
if not interface_type in network_types.values():
network_types[iface] = interface_type
for ip in addrs:
if network_types.has_key(iface):
params = addrs[ip]
if params['family'] == 'inet':
network['ipaddress_%s' % network_types[iface]] = ip
if params['family'] == 'inet6':
network['ipaddress6_%s' % network_types[iface]] = ip
if params['family'] == 'lladdr':
network['macaddress_%s' % network_types[iface]] = ip
# adapted from ohai network_nat plugin, if we need to look at more providers
# can update this later
conn = httplib.HTTPConnection('')
conn.request('GET', '/')
r1 = conn.getresponse()
if r1.status == 200:
content =
content = content.rstrip()
if re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", content):
network['ipaddress_nat'] = content
raise Exception('Invalid ip address %s' % content)
raise Exception('Bad response from server %s,%s' % (r1.status, r1.reason))
# dumb things that are apparently required for our recipes, look into why
# later
node['fqdn'] = runner.env.host_string
node['domain'] = ".".join(node['fqdn'].split(".")[1:])
node['network'] = network
node['hostname'] = ohai['hostname']
node['ipaddress'] = ohai['ipaddress']
# skip the cloud if bootstrapping a physical node
if 'cloud' in ohai:
node['cloud'] = ohai['cloud']
node['cloud']['uuid'] = 'N/A'
# Check if the /user/bin/xenstore-read file exists on
# the box being fixed. To do this, we need to execute
# Python locally. So we run python -c and send in the
# command we want to execute.
command = "python -c \"import os;print os.path.exists('/usr/bin/xenstore-read')\""
if sudo(command) == 'True':
output = sudo("/usr/bin/xenstore-read name")
node['cloud']['uuid'] = str(output)
node['keys'] = ohai['keys']
node['reach_environment'] = get_environment(node['name'])
os.remove(chef.save_config(node, force=True))
from fabric.api import sudo
def execute(node):
Install Chef 10.x with Omnibus installer
sudo("apt-get remove -y ruby1.8")
sudo("apt-get install -y ruby1.9.3")
sudo("curl -L | sudo bash -s -- -v 10.18.2")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment