-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from hudl/STRUCT-AddIISNodeType
Add IISNode IICluster and Autoscaler classes
- Loading branch information
Showing
8 changed files
with
708 additions
and
120 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
from mongo import MongoCluster | ||
from iis import IISCluster | ||
from autoscaling import AutoScaler |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
from boto.ec2.autoscale import LaunchConfiguration | ||
from boto.ec2.autoscale import AutoScalingGroup | ||
import boto.ec2 | ||
import logging | ||
|
||
|
||
class AutoScaler(object): | ||
''' | ||
Autoscaler setup class | ||
''' | ||
def __init__(self, launch_configuration, | ||
autoscaling_group, | ||
node_obj, | ||
desired_capacity=1, | ||
max_size=1, | ||
min_size=1, | ||
default_cooldown=300, | ||
availability_zones=None, | ||
subnet_ids=None, | ||
health_check_grace_period=300): | ||
self.log = logging.getLogger('tyr.clusters.AutoScaler') | ||
self.log.setLevel(logging.DEBUG) | ||
|
||
self.launch_configuration = launch_configuration | ||
self.autoscaling_group = autoscaling_group | ||
self.desired_capacity = desired_capacity | ||
|
||
# You can set a list of availability zones explicitly, else it will | ||
# just use the one from the node object | ||
if availability_zones: | ||
self.autoscale_availability_zones = availability_zones | ||
else: | ||
self.autoscale_availability_zones = None | ||
|
||
# If you set these they must match the availability zones | ||
if subnet_ids: | ||
self.autoscale_subnets = subnet_ids | ||
else: | ||
self.autoscale_subnets = None # TODO: (get the subnet IDs) | ||
|
||
if not subnet_ids and not availability_zones: | ||
self.log.critical( | ||
"Must specify either availability_zones or subnets.") | ||
raise ValueError( | ||
"Must specify either availability_zones or subnets.") | ||
|
||
if subnet_ids and availability_zones: | ||
self.log.warning("Specified both availability_zones and subnets.") | ||
|
||
self.node_obj = node_obj | ||
self.max_size = max_size | ||
self.min_size = min_size | ||
self.default_cooldown = default_cooldown | ||
self.health_check_grace_period = health_check_grace_period | ||
|
||
def establish_autoscale_connection(self): | ||
try: | ||
self.conn = boto.ec2.autoscale.connect_to_region( | ||
self.node_obj.region) | ||
self.log.info('Established connection to autoscale') | ||
except: | ||
raise | ||
|
||
def create_launch_configuration(self): | ||
self.log.info("Getting launch_configuration: {l}" | ||
.format(l=self.launch_configuration)) | ||
|
||
lc = self.conn.get_all_launch_configurations( | ||
names=[self.launch_configuration]) | ||
if not lc: | ||
self.log.info("Creating new launch_configuration: {l}" | ||
.format(l=self.launch_configuration)) | ||
lc = LaunchConfiguration(name=self.launch_configuration, | ||
image_id=self.node_obj.ami, | ||
key_name=self.node_obj.keypair, | ||
security_groups=self.node_obj. | ||
get_security_group_ids( | ||
self.node_obj.security_groups), | ||
user_data=self.node_obj.user_data, | ||
instance_profile_name=self.node_obj.role) | ||
self.conn.create_launch_configuration(lc) | ||
self.launch_configuration = lc | ||
|
||
def create_autoscaling_group(self): | ||
existing_asg = self.conn.get_all_groups( | ||
names=[self.autoscaling_group]) | ||
|
||
if not existing_asg: | ||
self.log.info("Creating new autoscaling group: {g}" | ||
.format(g=self.autoscaling_group)) | ||
|
||
ag = AutoScalingGroup(name=self.autoscaling_group, | ||
availability_zones=self. | ||
autoscale_availability_zones, | ||
desired_capacity=self.desired_capacity, | ||
health_check_period=self. | ||
health_check_grace_period, | ||
launch_config=self.launch_configuration, | ||
min_size=self.min_size, | ||
max_size=self.max_size, | ||
default_cooldown=self.default_cooldown, | ||
vpc_zone_identifier=self.autoscale_subnets, | ||
connection=self.conn) | ||
self.conn.create_auto_scaling_group(ag) | ||
else: | ||
self.log.info('Autoscaling group {g} already exists.' | ||
.format(g=self.autoscaling_group)) | ||
|
||
def autorun(self): | ||
self.establish_autoscale_connection() | ||
self.create_launch_configuration() | ||
self.create_autoscaling_group() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import logging | ||
from tyr.servers.iis import IISNode | ||
from tyr.clusters.autoscaling import AutoScaler | ||
|
||
|
||
class IISCluster(): | ||
|
||
def __init__(self, group=None, | ||
server_type=None, | ||
instance_type=None, | ||
environment=None, | ||
ami=None, | ||
region=None, | ||
subnet_ids=[], | ||
role=None, | ||
keypair=None, | ||
security_groups=None, | ||
autoscaling_group=None, | ||
desired_capacity=1, | ||
max_size=1, | ||
min_size=1, | ||
default_cooldown=300, | ||
availability_zones=None, | ||
health_check_grace_period=300, | ||
launch_configuration=None): | ||
|
||
self.log = logging.getLogger('tyr.clusters.IISCluster') | ||
self.group = group | ||
self.server_type = server_type | ||
self.instance_type = instance_type | ||
self.environment = environment | ||
self.ami = ami | ||
self.region = region | ||
self.role = role | ||
self.subnet_ids = subnet_ids | ||
|
||
self.keypair = keypair | ||
self.security_groups = security_groups | ||
self.autoscaling_group = autoscaling_group | ||
self.desired_capacity = desired_capacity | ||
self.max_size = max_size | ||
self.min_size = min_size | ||
self.default_cooldown = default_cooldown | ||
self.availability_zones = availability_zones | ||
self.health_check_grace_period = health_check_grace_period | ||
self.launch_configuration = launch_configuration | ||
|
||
if subnet_ids: | ||
self.node_subnet = self.subnet_ids[0] | ||
else: | ||
self.node_subnet = None | ||
|
||
if self.availability_zones: | ||
self.node_zone = availability_zones[0] | ||
else: | ||
self.node_zone = None | ||
|
||
def provision(self): | ||
|
||
self.log.info('Provisioning IISCluster') | ||
if not self.launch_configuration: | ||
self.launch_configuration = "{0}-{1}-web".format( | ||
self.environment[0], self.group) | ||
if not self.autoscaling_group: | ||
if self.subnet_ids: | ||
templ = "{0}-{1}-web-asg-vpc" | ||
else: | ||
templ = "{0}-{1}-web-asg" | ||
self.autoscaling_group = templ.format( | ||
self.environment[0], self.group) | ||
|
||
# Template to use with an autoscaling group | ||
node = IISNode(group=self.group, | ||
server_type=self.server_type, | ||
instance_type=self.instance_type, | ||
environment=self.environment, | ||
ami=self.ami, | ||
region=self.region, | ||
role=self.role, | ||
keypair=self.keypair, | ||
availability_zone=self.node_zone, | ||
security_groups=self.security_groups, | ||
subnet_id=self.node_subnet) | ||
node.configure() | ||
|
||
self.log.info('Creating autoscaler') | ||
auto = AutoScaler(launch_configuration=self.launch_configuration, | ||
autoscaling_group=self.autoscaling_group, | ||
desired_capacity=self.desired_capacity, | ||
max_size=self.max_size, | ||
min_size=self.min_size, | ||
default_cooldown=self.default_cooldown, | ||
availability_zones=self.availability_zones, | ||
subnet_ids=self.subnet_ids, | ||
health_check_grace_period=self. | ||
health_check_grace_period, | ||
node_obj=node) | ||
auto.autorun() | ||
|
||
def baked(self): | ||
return all([node.baked() for node in self.nodes]) | ||
|
||
def autorun(self): | ||
self.provision() |
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
Oops, something went wrong.