Created
March 21, 2012 20:55
-
-
Save clayrichardson/2152768 to your computer and use it in GitHub Desktop.
Create and tag Cassandra cluster on RightScale
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, urllib, httplib2, base64, json, re, time, paramiko | |
from operator import itemgetter | |
import pprint | |
headers = {} | |
cookie = '' | |
url_tail = '?api_version=1.0&format=js' | |
def create_url(method=None): | |
base_url = 'https://my.rightscale.com/api/acct/%s/' % account_id | |
return base_url + method + url_tail | |
def login(username=None, password=None, account_id=None): | |
base64string = base64.encodestring('%s:%s' % (username, password))[:-1] | |
headers['Authorization'] = "Basic %s" % base64string | |
response, content = api_request(create_url(method='login'), headers=headers) | |
headers['Cookie'] = response['set-cookie'] | |
def rightscale_request(method=None): | |
http_request = httplib2.Http() | |
return api_request(create_url(method=method), headers=headers) | |
def api_request(url=None, method='GET', body=None, headers=headers): | |
http_request = httplib2.Http() | |
print "Getting URL: ", url | |
return http_request.request(uri=url, method=method, headers=headers, body=body) | |
def get_array_servers(array_id): | |
request_url = 'https://my.rightscale.com/api/acct/%s/server_arrays/%s/instances' % (account_id, array_id) | |
response, content = api_request(request_url + url_tail) | |
print 'Response: ', response | |
return json.loads(content) | |
def get_array_nickname(array_id): | |
request_url = 'https://my.rightscale.com/api/acct/%s/server_arrays/%s' % (account_id, array_id) | |
response, content = api_request(request_url + url_tail) | |
return json.loads(content)['nickname'] | |
def add_servers_to_array(number_of_servers, array_id): | |
array_launch_url = 'https://my.rightscale.com/api/acct/%s/server_arrays/%s/launch' % (account_id, array_id) | |
for i in range(number_of_servers): | |
response, content = api_request(url=array_launch_url + url_tail, method='POST') | |
print 'Response: ', response | |
print 'Content: ', content | |
if __name__ == '__main__': | |
import rs_config | |
### you need to make an rs_config file | |
### that contains the following information | |
user = rs_config.user | |
password = rs_config.password | |
account_id = rs_config.account_id | |
array_id = rs_config.array_id | |
key_filename = rs_config.key_filename | |
cassandra_arrays = [] | |
cassandra_hrefs = [] | |
login(user, password, account_id) | |
cassandra_re = re.compile('cassandra', re.I) | |
response, content = rightscale_request('server_arrays') | |
server_arrays = json.loads(content) | |
for server_array in server_arrays: | |
if re.search(cassandra_re, server_array['nickname']): | |
cassandra_arrays.append(server_array) | |
pprint.pprint(cassandra_arrays) | |
for cassandra_array in cassandra_arrays: | |
cassandra_hrefs.append(cassandra_array['href']) | |
# uncomment to launch new instances | |
# add_servers_to_array(5, array_id) | |
cassandra_instances = get_array_servers(array_id) | |
cluster_operational_flag = False | |
cluster_stranded_flag = False | |
sorted_instances = sorted(cassandra_instances, key=itemgetter('nickname')) | |
while not cluster_operational_flag: | |
without_internal = [] | |
without_external = [] | |
pending = [] | |
booting = [] | |
operational = [] | |
cluster_operational_flag = True | |
cluster_details = {} | |
for instance in sorted_instances: | |
cluster_details[instance['nickname']] = [ | |
instance['ip_address'], | |
instance['private_ip_address'], | |
instance['state'], | |
] | |
if instance['ip_address'] == None: | |
cluster_operational_flag = False | |
without_external.append(instance) | |
if instance['private_ip_address'] == None: | |
cluster_operational_flag = False | |
without_internal.append(instance) | |
if instance['state'] == 'pending': | |
pending.append(instance) | |
if instance['state'] == 'booting': | |
booting.append(instance) | |
if instance['state'] == 'operational': | |
operational.append(instance) | |
if instance['state'] != 'operational': | |
cluster_operational_flag = False | |
if instance['state'] == 'stranded': | |
cluster_operational_flag = False | |
cluster_stranded_flag = True | |
print "CLUSTER STRANDED!" | |
exit() | |
pprint.pprint(cluster_details) | |
print "%s instances in cluster: %s pending, %s booting, %s without internal ip, %s without external ip, %s operational" % (len(sorted_instances), len(pending), len(booting), len(without_internal), len(without_external), len(operational)) | |
if not cluster_operational_flag: | |
print "cluster not ready yet, sleeping 5 seconds before checking again", | |
for i in range(5): | |
sys.stdout.write('.') | |
time.sleep(1) | |
sys.stdout.write('\n') | |
sys.stdout.flush() | |
cassandra_instances = get_array_servers(array_id) | |
sorted_instances = sorted(cassandra_instances, key=itemgetter('nickname')) | |
print "cluster ready to tag shit!" | |
cassandra_instances = get_array_servers(array_id) | |
array_nickname = get_array_nickname(array_id) | |
sorted_instances = sorted(cassandra_instances, key=itemgetter('nickname'), reverse=True) | |
# because rightscale doesn't support running | |
# rightscripts on individual servers in an array, | |
# we need to ssh into each one to tag them with | |
# their node numbers | |
instance_number = 0 | |
for instance in sorted_instances: | |
pprint.pprint(instance) | |
ssh = paramiko.SSHClient() | |
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | |
ssh.connect(instance['ip_address'], username='root', key_filename=key_filename) | |
commands = [ | |
'rs_tag -a "ip:internal=%s"' % instance['private_ip_address'], | |
'rs_tag -a "ip:external=%s"' % instance['ip_address'], | |
'rs_tag -a "cassandra:node=%s"' % instance_number, | |
'rs_tag -a "cassandra:cluster=%s"' % array_nickname, | |
] | |
for command in commands: | |
stdin, stdout, stderr = ssh.exec_command(command) | |
print stdout.readlines() | |
ssh.close() | |
instance_number = instance_number + 1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment