Esempio n. 1
0
def deploy_new_version(region,
                       cluster_name,
                       ecs_service_name,
                       deploy_version_tag,
                       service_name,
                       sample_env_file_path,
                       env_name,
                       color='white',
                       complete_image_uri=None):
    env_config = build_config(env_name, service_name, sample_env_file_path)
    client = EcsClient(None, None, region)
    deployment = DeployAction(client, cluster_name, ecs_service_name)
    if deployment.service.desired_count == 0:
        desired_count = 1
    else:
        desired_count = deployment.service.desired_count
    deployment.service.set_desired_count(desired_count)
    task_definition = deployment.get_current_task_definition(
        deployment.service)
    if complete_image_uri is not None:
        container_name = task_definition['containerDefinitions'][0]['name']
        task_definition.set_images(deploy_version_tag,
                                   **{container_name: complete_image_uri})
    else:
        task_definition.set_images(deploy_version_tag)
    for container in task_definition.containers:
        task_definition.apply_container_environment(container, env_config)
    print_task_diff(ecs_service_name, task_definition.diff, color)
    new_task_definition = deployment.update_task_definition(task_definition)
    response = deploy_and_wait(deployment, new_task_definition, color)
    if response:
        log_bold(ecs_service_name + " Deployed successfully.")
    else:
        log_err(ecs_service_name + " Deployment failed.")
    return response
 def _fetch_current_desired_count(self):
     stack_name = get_service_stack_name(self.env, self.application_name)
     self.desired_counts = {}
     try:
         stack = region_service.get_client_for(
             'cloudformation',
             self.env
         ).describe_stacks(StackName=stack_name)['Stacks'][0]
         ecs_service_outputs = filter(
             lambda x: x['OutputKey'].endswith('EcsServiceName'),
             stack['Outputs']
         )
         ecs_service_names = []
         for service_name in ecs_service_outputs:
             ecs_service_names.append({
                 "key": service_name['OutputKey'],
                 "value": service_name['OutputValue']
             })
         ecs_client = EcsClient(None, None, self.region)
         for service_name in ecs_service_names:
             deployment = DeployAction(
                 ecs_client,
                 self.cluster_name,
                 service_name["value"]
             )
             actual_service_name = service_name["key"]. \
                 replace("EcsServiceName", "")
             self.desired_counts[actual_service_name] = deployment. \
                 service.desired_count
         log("Existing service counts: " + str(self.desired_counts))
     except Exception:
         log_bold("Could not find existing services.")
Esempio n. 3
0
def deploy_new_version(cluster_name,
                       ecs_service_name,
                       ecs_service_logical_name,
                       deployment_identifier,
                       service_name,
                       sample_env_file_path,
                       timeout_seconds,
                       env_name,
                       secrets_name,
                       service_configuration,
                       region,
                       ecr_image_uri,
                       color='white'):
    client = EcsClient(None, None, region)
    task_definition = create_new_task_definition(
        color=color,
        ecr_image_uri=ecr_image_uri,
        ecs_service_name=ecs_service_name,
        env_name=env_name,
        sample_env_file_path=sample_env_file_path,
        secrets_name=secrets_name,
        service_name=service_name,
        client=client,
        cluster_name=cluster_name,
        deployment_identifier=deployment_identifier,
        ecs_service_logical_name=ecs_service_logical_name,
        service_configuration=service_configuration,
        region=region,
    )
    deploy_task_definition(client, task_definition, cluster_name,
                           ecs_service_name, color, timeout_seconds, 'Deploy')
Esempio n. 4
0
    def test_get_task_definition_by_deployment_identifier_with_next_token(
            self, mock_session):
        cluster_name = "cluster-1"
        service_name = MagicMock()
        service_name.task_definition.return_value.family.return_value = "prodServiceAFamily"
        mock_boto_client = MagicMock()
        mock_session.return_value.client.return_value = mock_boto_client

        client = EcsClient()

        mock_boto_client.list_task_definitions.side_effect = [
            {
                'taskDefinitionArns': ['arn1', 'arn2'],
                'nextToken': 'token1'
            },
            {
                'taskDefinitionArns': ['arn3', 'arn3']
            },
        ]

        def mock_describe_task_definition(taskDefinition, include):
            if taskDefinition == 'arn3':
                return {
                    'taskDefinition': {
                        'taskDefinitionArn': taskDefinition,
                        'family': 'tdFamily'
                    },
                    'tags': [
                        {
                            'key': 'deployment_identifier',
                            'value': 'id-0'
                        },
                    ]
                }
            else:
                return {
                    'taskDefinition': {
                        'taskDefinitionArn': taskDefinition,
                        'family': 'tdFamily'
                    },
                    'tags': {}
                }

        mock_boto_client.describe_task_definition.side_effect = mock_describe_task_definition

        action = EcsAction(client, cluster_name, service_name)

        actual_td = action.get_task_definition_by_deployment_identifier(
            service=service_name, deployment_identifier="id-0")

        self.assertEqual('arn3', actual_td.arn)
        self.assertEqual({'deployment_identifier': 'id-0'}, actual_td.tags)
        mock_boto_client.list_task_definitions.assert_has_calls([
            call(familyPrefix='tdFamily', status='ACTIVE', sort='DESC'),
            call(familyPrefix='tdFamily',
                 status='ACTIVE',
                 sort='DESC',
                 nextToken='token1')
        ])
Esempio n. 5
0
def revert_deployment(cluster_name, ecs_service_name, color, timeout_seconds,
                      deployment_identifier, region, **kwargs):
    client = EcsClient(None, None, region)
    deployment = DeployAction(client, cluster_name, ecs_service_name)
    previous_task_defn = deployment.get_task_definition_by_deployment_identifier(
        deployment.service, deployment_identifier)
    deploy_task_definition(client, previous_task_defn, cluster_name,
                           ecs_service_name, color, timeout_seconds, 'Revert')
 def fetch_current_desired_count(self):
     desired_counts = {}
     try:
         deployment_ecs_client = EcsClient(
             None, None, get_region_for_environment(self.environment))
         for logical_service_name, service_config in self.service_info.items(
         ):
             deployment = DeployAction(deployment_ecs_client,
                                       self.cluster_name,
                                       service_config["ecs_service_name"])
             desired_counts[
                 logical_service_name] = deployment.service.desired_count
         log("Existing service counts: " + str(desired_counts))
     except Exception:
         pass
     return desired_counts
 def fetch_current_desired_count(self):
     desired_counts = {}
     try:
         deployment_ecs_client = EcsClient(
             None, None, get_region_for_environment(self.environment))
         for logical_service_name, service_config in self.service_info.items(
         ):
             deployment = DeployAction(deployment_ecs_client,
                                       self.cluster_name,
                                       service_config["ecs_service_name"])
             if deployment.service:
                 desired_counts[
                     logical_service_name] = deployment.service.desired_count
         log("Existing service counts: " + str(desired_counts))
     except Exception as e:
         raise UnrecoverableException(
             "Could not find existing services. {}".format(e))
     return desired_counts
Esempio n. 8
0
    def run(self):
        log_warning("Deploying to {self.region}".format(**locals()))
        self.init_stack_info()
        if not os.path.exists(self.env_sample_file):
            raise UnrecoverableException('env.sample not found. Exiting.')
        log_intent("name: " + self.name + " | environment: " +
                   self.environment + " | version: " + str(self.version))
        log_bold("Checking image in ECR")
        self.upload_artefacts()
        log_bold("Initiating deployment\n")
        ecs_client = EcsClient(None, None, self.region)

        jobs = []
        for index, service_name in enumerate(self.ecs_service_names):
            log_bold("Starting to deploy " + service_name)
            color = DEPLOYMENT_COLORS[index % 3]
            image_url = self.ecr_image_uri
            image_url += (':' + self.version)
            process = multiprocessing.Process(
                target=deployer.deploy_new_version,
                args=(
                    ecs_client,
                    self.cluster_name,
                    service_name,
                    self.version,
                    self.name,
                    self.env_sample_file,
                    self.environment,
                    color,
                    image_url
                )
            )
            jobs.append(process)
            process.start()

        exit_codes = []
        while True:
            sleep(1)
            exit_codes = [proc.exitcode for proc in jobs]
            if None not in exit_codes:
                break

        if any(exit_codes) != 0:
            raise UnrecoverableException("Deployment failed")
Esempio n. 9
0
    def run(self):
        log_warning("Deploying to {self.region}".format(**locals()))
        if not os.path.exists(self.env_sample_file):
            raise UnrecoverableException('env.sample not found. Exiting.')
        log_intent("name: " + self.name + " | environment: " +
                   self.environment + " | version: " + str(self.version) +
                   " | deployment_identifier: " + self.deployment_identifier)
        log_bold("Checking image in ECR")
        self.ecr.upload_artefacts()
        log_bold("Initiating deployment\n")
        ecs_client = EcsClient(None, None, self.region)

        image_url = self.ecr.image_uri
        target = deployer.deploy_new_version
        kwargs = dict(client=ecs_client, cluster_name=self.cluster_name,
                      service_name=self.name, sample_env_file_path=self.env_sample_file,
                      timeout_seconds=self.timeout_seconds, env_name=self.environment,
                      ecr_image_uri=image_url,
                      deployment_identifier=self.deployment_identifier,
                      )
        self.run_job_for_all_services("Deploy", target, kwargs)
Esempio n. 10
0
    def test_get_task_definition_by_deployment_identifier_with_no_matches(
            self, mock_session):
        cluster_name = "cluster-1"
        service_name = MagicMock()
        service_name.task_definition.return_value.family.return_value = "stgServiceAFamily"
        mock_boto_client = MagicMock()
        mock_session.return_value.client.return_value = mock_boto_client

        client = EcsClient()

        mock_boto_client.list_task_definitions.side_effect = [
            {
                'taskDefinitionArns': ['arn1', 'arn2'],
                'nextToken': 'token1'
            },
            {
                'taskDefinitionArns': ['arn3', 'arn3']
            },
        ]

        def mock_describe_task_definition(taskDefinition, include):
            return {
                'taskDefinition': {
                    'taskDefinitionArn': taskDefinition,
                    'family': 'tdFamily'
                },
                'tags': {}
            }

        mock_boto_client.describe_task_definition.side_effect = mock_describe_task_definition

        action = EcsAction(client, cluster_name, service_name)

        with self.assertRaises(UnrecoverableException) as error:
            action.get_task_definition_by_deployment_identifier(
                service=service_name, deployment_identifier="id-0")

        self.assertEqual(
            "task definition does not exist for deployment_identifier: id-0",
            error.exception.value)
Esempio n. 11
0
 def revert(self):
     target = deployer.revert_deployment
     ecs_client = EcsClient(None, None, self.region)
     kwargs = dict(client=ecs_client, cluster_name=self.cluster_name, timeout_seconds=self.timeout_seconds,
                   deployment_identifier=self.deployment_identifier)
     self.run_job_for_all_services("Revert", target, kwargs)