Esempio n. 1
0
def purge_launch_configuration(cloud_connection, app, retention):
    """
    Removes the old launch configurations except the `retention`th latest
    :param cloud_connection: object:
    :param app: object:
    :param retention: int:
    :return: bool:
    """
    conn_as = cloud_connection.get_connection(app['region'], ["autoscaling"],
                                              boto_version='boto3')
    paginator = conn_as.get_paginator('describe_launch_configurations')
    lcs = []
    for page in paginator.paginate():
        lcs = lcs + page['LaunchConfigurations']

    blue_green, app_color = get_blue_green_from_app(app)
    launchconfig_prefix = _format_launchconfig_name(app,
                                                    app_color,
                                                    only_prefix=True)

    lcs = [
        lc for lc in lcs
        if lc['LaunchConfigurationName'].startswith(launchconfig_prefix)
    ]
    lcs = sorted(lcs, key=lambda lc: lc['CreatedTime'],
                 reverse=True)[retention:]

    for lc in lcs:
        try:
            conn_as.delete_launch_configuration(
                LaunchConfigurationName=lc['LaunchConfigurationName'])
        except ClientError as e:
            if e.response.get('Error', {}).get('Code') != 'ResourceInUse':
                raise
    return True
Esempio n. 2
0
def create_launch_config(cloud_connection, app, userdata, ami_id):
    blue_green, app_color = get_blue_green_from_app(app)

    launchconfig_name = _format_launchconfig_name(app, app_color)
    conn_as = cloud_connection.get_connection(app['region'],
                                              ["ec2", "autoscale"])
    instance_monitoring = app.get('instance_monitoring', False)
    launch_config = cloud_connection.launch_service(
        ["ec2", "autoscale", "LaunchConfiguration"],
        connection=conn_as,
        name=launchconfig_name,
        image_id=ami_id,
        key_name=app['environment_infos']['key_name'],
        security_groups=app['environment_infos']['security_groups'],
        user_data=userdata,
        instance_type=app['instance_type'],
        kernel_id=None,
        ramdisk_id=None,
        block_device_mappings=get_block_devices_mapping(cloud_connection, app),
        instance_monitoring=instance_monitoring,
        spot_price=None,
        instance_profile_name=app['environment_infos']['instance_profile'],
        ebs_optimized=False,
        associate_public_ip_address=app['environment_infos'].get(
            'public_ip_address', True),
        volume_type=None,
        delete_on_termination=True,
        iops=None,
        classic_link_vpc_id=None,
        classic_link_vpc_security_groups=None)
    conn_as.create_launch_configuration(launch_config)
    return launch_config
Esempio n. 3
0
def is_available(app_context=None):
    ghost_has_blue_green = ghost_has_blue_green_enabled()
    if not ghost_has_blue_green:
        return False
    if not app_context:
        return True
    app_blue_green, app_color = get_blue_green_from_app(app_context)
    return app_blue_green is not None and app_color is not None
Esempio n. 4
0
def post_update_app(updates, original):
    try:
        # Enable green app only if not already enabled
        blue_green, color = get_blue_green_from_app(original)
        if ghost_api_bluegreen_is_enabled(updates) and not color:
            # Maybe we need to have the "merged" app after update here instead of "original" one ?
            if not ghost_api_enable_green_app(get_apps_db(), original,
                                              request.authorization.username):
                abort(422)
    except Exception as e:
        print "Exception occured"
        print e
        abort(500)
Esempio n. 5
0
 def __init__(self, worker):
     self._app = worker.app
     self._job = worker.job
     self._config = worker._config
     self._worker = worker
     self._log_file = worker.log_file
     self._connection_data = get_aws_connection_data(
         self._app.get('assumed_account_id', ''),
         self._app.get('assumed_role_name', ''),
         self._app.get('assumed_region_name', ''))
     self._cloud_connection = cloud_connections.get(
         self._app.get('provider',
                       DEFAULT_PROVIDER))(self._config,
                                          **self._connection_data)
     blue_green, self._color = get_blue_green_from_app(self._app)
Esempio n. 6
0
    def __init__(self, app, job, db, log_file, config):

        self._app = app
        self._job = job
        self._db = db
        self._log_file = log_file
        self._config = config

        blue_green, self._color = get_blue_green_from_app(self._app)
        self._ami_name = AMI_FMT.format(env=self._app['env'],
                                        region=self._app['region'],
                                        role=self._app['role'],
                                        name=self._app['name'],
                                        date=time.strftime("%Y%m%d-%H%M%S"),
                                        color='.%s' %
                                        self._color if self._color else '')
        self.unique = str(job['_id'])
        self.packer_directory_path = os.path.join(PACKER_JSON_PATH,
                                                  self.unique)
        if not os.path.exists(self.packer_directory_path):
            os.makedirs(self.packer_directory_path)
Esempio n. 7
0
def ghost_api_check_green_app_exists(apps_db, app):
    """
    Check if the Alter Ego application exists
    ie: the blue one or the green one (depending of the current app color)
    """
    name = app.get('name')
    role = app.get('role')
    env = app.get('env')
    blue_green, color = get_blue_green_from_app(app)
    if not color:
        color = 'blue'  # handle default one
    green_app = apps_db.find_one({
        '$and': [{
            'name': name
        }, {
            'role': role
        }, {
            'env': env
        }, {
            'blue_green.color': OPPOSITE_COLOR[color]
        }]
    })
    return green_app
Esempio n. 8
0
def pre_update_app(updates, original):
    """
    eve pre-update event hook to reset modified modules' 'initialized' field.

    Uninitialized modules stay so, modified or not:

    >>> from copy import deepcopy
    >>> base_original = {'_id': 1111, 'env': 'prod', 'name': 'app1', 'role': 'webfront', 'modules': [
    ...     {'name': 'mod1', 'git_repo': '[email protected]/test/mod1', 'path': '/tmp/ok'},
    ...     {'name': 'mod2', 'git_repo': '[email protected]/test/mod2', 'path': '/tmp/ok'}],
    ... 'environment_infos': {'instance_tags':[]}}
    >>> original = deepcopy(base_original)
    >>> updates = deepcopy(base_original)
    >>> pre_update_app(updates, original)
    >>> updates['modules'][0]['initialized']
    False
    >>> updates['modules'][1]['initialized']
    False

    Initialized modules stay so if not modified:

    >>> original['modules'][0]['initialized'] = True
    >>> original['modules'][1]['initialized'] = True
    >>> updates = deepcopy(base_original)
    >>> pre_update_app(updates, original)
    >>> updates['modules'][0]['initialized']
    True
    >>> updates['modules'][1]['initialized']
    True

    Modified modules get their 'initialized' field reset to False:

    >>> updates = deepcopy(base_original)
    >>> updates['modules'][1]['git_repo'] = '[email protected]/test/mod2-modified'
    >>> pre_update_app(updates, original)
    >>> updates['modules'][0]['initialized']
    True
    >>> updates['modules'][1]['initialized']
    False

    Modified modules get their 'initialized' field reset to False also in case of new fields:

    >>> updates = deepcopy(base_original)
    >>> updates['modules'][1]['uid'] = '101'
    >>> updates['modules'][1]['gid'] = '102'
    >>> pre_update_app(updates, original)
    >>> updates['modules'][0]['initialized']
    True
    >>> updates['modules'][1]['initialized']
    False

    New modules get their 'initialized' field set to False by default:

    >>> updates = deepcopy(base_original)
    >>> updates['modules'].append({'name': 'mod3', 'git_repo': '[email protected]/test/mod3', 'path': '/tmp/ok'})
    >>> pre_update_app(updates, original)
    >>> updates['modules'][0]['initialized']
    True
    >>> updates['modules'][1]['initialized']
    True
    >>> updates['modules'][2]['initialized']
    False
    """

    try:
        ghost_api_app_data_input_validator(updates)
    except GhostAPIInputError as error:
        abort(422, description=error.message)

    # Selectively reset each module's 'initialized' property if any of its other properties have changed
    updates, modules_edited = initialize_app_modules(updates, original)
    user = request.authorization.username if request and request.authorization else 'Nobody'
    updates = check_and_set_app_fields_state(user, updates, original,
                                             modules_edited)

    if 'environment_infos' in updates and 'instance_tags' in updates[
            'environment_infos']:
        updates['environment_infos'][
            'instance_tags'] = normalize_application_tags(original, updates)

    # Blue/green disabled ?
    try:
        blue_green_section, color = get_blue_green_from_app(updates)
        if (blue_green_section and 'enable_blue_green' in blue_green_section
                and isinstance(blue_green_section['enable_blue_green'], bool)
                and not blue_green_section['enable_blue_green']):

            if not ghost_api_clean_bluegreen_app(get_apps_db(), original):
                abort(422)

            if not ghost_api_delete_alter_ego_app(get_apps_db(), original):
                abort(422)

            del updates['blue_green']
    except Exception as e:
        print e
        abort(500)