Skip to content

Commit

Permalink
Merge pull request #37 from nz285/DEVOPS-7572
Browse files Browse the repository at this point in the history
DEVOPS-7572: added 'force' switch to force creating new instances
  • Loading branch information
nz285 committed Sep 30, 2016
2 parents 087b4e5 + 498f16c commit e60802d
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
9 changes: 8 additions & 1 deletion License2Deploy/rolling_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def __init__(self,
profile_name=None,
regions_conf=None,
stack_name=None,
force_redeploy=False,
session=None,
creation_wait=[10, 60],
ready_wait=[10, 30],
Expand All @@ -33,6 +34,7 @@ def __init__(self,
self.profile_name = profile_name
self.regions_conf = regions_conf
self.stack_name = stack_name
self.force_redeploy = force_redeploy
self.stack_resources = False
self.autoscaling_groups = False
self.cloudwatch_alarms = False
Expand All @@ -49,6 +51,7 @@ def __init__(self,
self.ready_wait = ready_wait
self.health_wait = health_wait
self.only_new_wait = only_new_wait
self.existing_instance_ids = []

def get_ami_id_state(self, ami_id):
try:
Expand Down Expand Up @@ -171,6 +174,8 @@ def get_instance_ids_by_requested_build_tag(self, id_list, build):
''' Gather Instance id's of all instances in the autoscale group '''
reservations = self.conn_ec2.get_all_reservations(instance_ids=id_list)
new_instances = []
if self.force_redeploy:
id_list = [id for id in id_list if id not in self.existing_instance_ids]
for instance_id in id_list:
instances_build_tags = [inst for r in reservations for inst in r.instances if 'BUILD' in inst.tags and inst.id == instance_id]
new_instances += [instance_id for new_id in instances_build_tags if new_id.tags['BUILD'] == str(build)]
Expand Down Expand Up @@ -325,6 +330,7 @@ def deploy(self): # pragma: no cover
group_name = self.get_autoscale_group_name()
self.wait_ami_availability(self.ami_id)
logging.info("Build #: {0} ::: Autoscale Group: {1}".format(self.build_number, group_name))
self.existing_instance_ids = list(self.get_all_instance_ids(group_name))
self.disable_project_cloudwatch_alarms()
self.set_autoscale_instance_desired_count(self.calculate_autoscale_desired_instance_count(group_name, 'increase'), group_name)
self.launch_new_instances(group_name)
Expand Down Expand Up @@ -357,6 +363,7 @@ def get_args(): # pragma: no cover
parser.add_argument('-P', '--profile', default='default', action='store', dest='profile', help='Profile name as designated in aws credentials/config files', type=str)
parser.add_argument('-c', '--config', default='/opt/License2Deploy/regions.yml', action='store', dest='config', help='Config file Location, eg. /opt/License2Deploy/regions.yml', type=str)
parser.add_argument('-s', '--stack', action='store', dest='stack_name', help='Stack name if AutoScaling Group created via CloudFormation', type=str)
parser.add_argument('-f', '--force-redeploy', action='store', dest='force_redeploy', help='Whether to force redeploy current running build', type=bool, default=False)
parser.add_argument('-C', '--creation-wait', action='store', dest='creation_wait', help='Wait time for ec2 instance creation', type=int, nargs=2, default=[10, 60])
parser.add_argument('-r', '--ready-wait', action='store', dest='ready_wait', help='Wait time for ec2 instance to be ready', type=int, nargs=2, default=[10, 30])
parser.add_argument('-H', '--health-wait', action='store', dest='health_wait', help='Wait time for ec2 instance health check', type=int, nargs=2, default=[10, 30])
Expand All @@ -366,7 +373,7 @@ def get_args(): # pragma: no cover
def main(): # pragma: no cover
args = get_args()
SetLogging.setup_logging()
deployObj = RollingDeploy(args.env, args.project, args.build_number, args.ami_id, args.profile, args.config, args.stack_name, None, args.creation_wait, args.ready_wait, args.health_wait, args.only_new_wait)
deployObj = RollingDeploy(args.env, args.project, args.build_number, args.ami_id, args.profile, args.config, args.stack_name, args.force_redeploy, None, args.creation_wait, args.ready_wait, args.health_wait, args.only_new_wait)
deployObj.deploy()

if __name__ == "__main__": # pragma: no cover
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Usage
==================
```
usage: rolling_deploy.py [-h] -e ENV -p PROJECT -b BUILD_NUM -a AMI_ID
[-P PROFILE] [-c CONFIG] [-s STACK_NAME]
[-P PROFILE] [-c CONFIG] [-s STACK_NAME] [-f FORCE_REDEPLOY]
[-C CREATION_WAIT] [-r READY_WAIT] [-H HEALTH_WAIT] [-o ONLY_NEW_WAIT]
optional arguments:
Expand All @@ -42,6 +42,8 @@ optional arguments:
/opt/License2Deploy/config.yml
-s STACK_NAME, --stack STACK_NAME
Stack name if AutoScaling Group created via CloudFormation
-f FORCE_REDEPLOY, --force-redeploy FORCE_REDEPLOY
Whether to force redeploy current running build, default to false
-C CREATION_WAIT, --creation-wait CREATION_WAIT
Time to wait for EC2 instances to be created
(# of tries, interval of each try in seconds), default (10, 60)
Expand Down
7 changes: 7 additions & 0 deletions tests/rolling_deploy_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ def test_get_instance_ids_by_requested_build_tag(self):
self.assertEqual(len(self.rolling_deploy.get_instance_ids_by_requested_build_tag(new_inst, 0)), 2)
self.assertRaises(Exception, lambda: self.rolling_deploy.get_instance_ids_by_requested_build_tag(new_inst, 1))

self.rolling_deploy.existing_instance_ids = list(new_inst)
self.rolling_deploy.force_redeploy = False
self.assertEqual(len(self.rolling_deploy.get_instance_ids_by_requested_build_tag(new_inst, 0)), 2)
self.rolling_deploy.force_redeploy = True
self.assertRaises(Exception, lambda: self.rolling_deploy.get_instance_ids_by_requested_build_tag(new_inst, 0))


@mock_ec2
def test_get_instance_ids_by_requested_build_tag_failure(self):
self.setUpEC2()
Expand Down

0 comments on commit e60802d

Please sign in to comment.