Example #1
0
 def test_get_ec2_details(self):
     print('test_get_ec2_details')
     ec2_resource = boto3.resource('ec2')
     ec2_linux_object, ec2_windows_object = generate_ec2(ec2_resource)
     linux = aws_services.get_ec2_details(ec2_linux_object, ec2_resource, '138339392836')
     windows = aws_services.get_ec2_details(ec2_windows_object, ec2_resource, '138339392836')
     self.assertIn('Amazon Linux', linux['image_description'])
     self.assertIn('Windows', windows['image_description'])
def elasticity_function(instance_id, action_type, event_account_id,
                        event_region, solution_account_id, log_name):
    try:
        ec2_object = aws_services.get_account_details(solution_account_id,
                                                      event_account_id,
                                                      event_region)
        instance_details = aws_services.get_ec2_details(
            instance_id, ec2_object, event_account_id)
        instance_data = aws_services.get_instance_data_from_dynamo_table(
            instance_id)
        if action_type == 'terminated':
            if not instance_data:
                logger.info(f"Item {instance_id} does not exist on DB")
                return None
            instance_status = instance_data["Status"]["S"]
            if instance_status == OnBoardStatus.on_boarded_failed:
                logger.error(
                    f"Item {instance_id} is in status OnBoard failed, removing from DynamoDB table"
                )
                aws_services.remove_instance_from_dynamo_table(instance_id)
                return None
        elif action_type == 'running':
            if not instance_details[
                    "address"]:  # In case querying AWS return empty address
                logger.error("Retrieving Instance Address from AWS failed.")
                return None
            if instance_data:
                instance_status = instance_data["Status"]["S"]
                if instance_status == OnBoardStatus.on_boarded:
                    logger.info(
                        f"Item {instance_id} already exists on DB, no need to add it to Vault"
                    )
                    return None
                elif instance_status == OnBoardStatus.on_boarded_failed:
                    logger.error(
                        f"Item {instance_id} exists with status 'OnBoard failed', adding to Vault"
                    )
                else:
                    logger.info(
                        f"Item {instance_id} does not exist on DB, adding to Vault"
                    )
        else:
            logger.info('Unknown instance state')
            return

        store_parameters_class = aws_services.get_params_from_param_store()
        if not store_parameters_class:
            return
        if store_parameters_class.aob_mode == 'Production':
            # Save PVWA Verification key in /tmp folder
            logger.info('Saving verification key')
            crt = open("/tmp/server.crt", "w+")
            crt.write(store_parameters_class.pvwa_verification_key)
            crt.close()
        pvwa_connection_number, session_guid = aws_services.get_session_from_dynamo(
        )
        if not pvwa_connection_number:
            return
        session_token = pvwa_integration_class.logon_pvwa(
            store_parameters_class.vault_username,
            store_parameters_class.vault_password,
            store_parameters_class.pvwa_url, pvwa_connection_number)
        if not session_token:
            return
        disconnect = False
        if action_type == 'terminated':
            logger.info(f'Detected termination of {instance_id}')
            instance_processing.delete_instance(instance_id, session_token,
                                                store_parameters_class,
                                                instance_data,
                                                instance_details)
        elif action_type == 'running':
            # get key pair
            logger.info('Retrieving account id where the key-pair is stored')
            # Retrieving the account id of the account where the instance keyPair is stored
            # AWS.<AWS Account>.<Event Region name>.<key pair name>
            key_pair_value_on_safe = f'AWS.{instance_details["aws_account_id"]}.{event_region}.{instance_details["key_name"]}'
            key_pair_account_id = pvwa_api_calls.check_if_kp_exists(
                session_token, key_pair_value_on_safe,
                store_parameters_class.key_pair_safe_name, instance_id,
                store_parameters_class.pvwa_url)
            if not key_pair_account_id:
                logger.error(f"Key Pair {key_pair_value_on_safe} does not exist in Safe " \
                             f"{store_parameters_class.key_pair_safe_name}")
                return
            instance_account_password = pvwa_api_calls.get_account_value(
                session_token, key_pair_account_id, instance_id,
                store_parameters_class.pvwa_url)
            if instance_account_password is False:
                return
            pvwa_integration_class.logoff_pvwa(store_parameters_class.pvwa_url,
                                               session_token)
            aws_services.release_session_on_dynamo(pvwa_connection_number,
                                                   session_guid)
            disconnect = True
            instance_processing.create_instance(instance_id, instance_details,
                                                store_parameters_class,
                                                log_name, solution_account_id,
                                                event_region, event_account_id,
                                                instance_account_password)
        else:
            logger.error('Unknown instance state')
            return

        if not disconnect:
            pvwa_integration_class.logoff_pvwa(store_parameters_class.pvwa_url,
                                               session_token)
            aws_services.release_session_on_dynamo(pvwa_connection_number,
                                                   session_guid)

    except Exception as e:
        logger.error(f"Unknown error occurred: {e}")
        if action_type == 'terminated':
            # put_instance_to_dynamo_table(instance_id, instance_details["address"]\
            # , OnBoardStatus.delete_failed, str(e), log_name)
            aws_services.update_instances_table_status(
                instance_id, OnBoardStatus.delete_failed, str(e))
        elif action_type == 'running':
            aws_services.put_instance_to_dynamo_table(
                instance_id, instance_details["address"],
                OnBoardStatus.on_boarded_failed, str(e), log_name)


# TODO: Retry mechanism?
        aws_services.release_session_on_dynamo(pvwa_connection_number,
                                               session_guid)
        return
Example #3
0
def lambda_handler(event, context):

    try:
        message = event["Records"][0]["Sns"]["Message"]
        data = json.loads(message)
    except Exception as e:
        print ("Error on retrieving Message Data from Event Message. Error: {0}".format(e))

    try:
        instance_arn = data["resources"][0]
    except Exception as e:
        print ("Error on retrieving instance_arn from Event Message. Error: {0}".format(e))

    try:
        instanceId = data["detail"]["instance-id"]
    except Exception as e:
        print ("Error on retrieving Instance Id from Event Message. Error: {0}".format(e))

    try:
        actionType = data["detail"]["state"]
    except Exception as e:
        print ("Error on retrieving Action Type from Event Message. Error: {0}".format(e))


    try:
        eventAccountId = data["account"]
    except Exception as e:
        print ("Error on retrieving Event Account Id from Event Message. Error: {0}".format(e))


    try:
        eventRegion = data["region"]
    except Exception as e:
        print ("Error on retrieving Event Region from Event Message. Error: {0}".format(e))


    logName = context.log_stream_name if context.log_stream_name else "None"

    try:
        solutionAccountId = context.invoked_function_arn.split(':')[4]
        instanceDetails = aws_services.get_ec2_details(instanceId, solutionAccountId, eventRegion, eventAccountId)

        instanceData = aws_services.get_instance_data_from_dynamo_table(instanceId)
        if actionType == 'terminated':
            if not instanceData:
                print('Item {0} does not exists on DB'.format(instanceId))
                return None
            else:
                instanceStatus = instanceData["Status"]["S"]
                if instanceStatus == OnBoardStatus.OnBoarded_Failed:
                    print("Item {0} is in status OnBoard failed, removing from DynamoDB table".format(instanceId))
                    aws_services.remove_instance_from_dynamo_table(instanceId)
                    return None
        elif actionType == 'running':
            if not instanceDetails["address"]:  # In case querying AWS return empty address
                print("Retrieving Instance address from AWS failed.")
                return None
            if instanceData:
                instanceStatus = instanceData["Status"]["S"]
                if instanceStatus == OnBoardStatus.OnBoarded:
                    print('Item: {0}, exists on DB, no need to add it to vault'.format(instanceId))
                    return None
                elif instanceStatus == OnBoardStatus.OnBoarded_Failed:
                    print("Item {0} exists with status 'OnBoard failed', adding to vault".format(instanceId))
                else:
                    print('Item {0} does not exists on DB, adding to vault'.format(instanceId))
        else:
            print('Unknown instance state')
            return

        storeParametersClass = aws_services.get_params_from_param_store()
        if not storeParametersClass:
            return
        pvwaConnectionnumber, sessionGuid = aws_services.get_available_session_from_dynamo()
        if not pvwaConnectionnumber:
            return
        sessionToken = pvwa_integration.logon_pvwa(storeParametersClass.vaultUsername,
                                                   storeParametersClass.vaultPassword,
                                                   storeParametersClass.pvwaURL, pvwaConnectionnumber)

        if not sessionToken:
            return
        disconnect = False
        if actionType == 'terminated':
            instance_processing.delete_instance(instanceId, sessionToken, storeParametersClass, instanceData, instanceDetails)
        elif actionType == 'running':
            # get key pair

            # Retrieving the account id of the account where the instance keyPair is stored
            # AWS.<AWS Account>.<Event Region name>.<key pair name>
            keyPairValueOnSafe = "AWS.{0}.{1}.{2}".format(instanceDetails["aws_account_id"], eventRegion,
                                                          instanceDetails["key_name"])
            keyPairAccountId = pvwa_api_calls.check_if_kp_exists(sessionToken, keyPairValueOnSafe,
                                                                                   storeParametersClass.keyPairSafeName,
                                                                                   instanceId,
                                                                                   storeParametersClass.pvwaURL)
            if not keyPairAccountId:
                print("Key Pair '{0}' does not exist in safe '{1}'".format(keyPairValueOnSafe,
                                                                           storeParametersClass.keyPairSafeName))
                return
            instanceAccountPassword = pvwa_api_calls.get_account_value(sessionToken, keyPairAccountId, instanceId,
                                                                       storeParametersClass.pvwaURL)
            if instanceAccountPassword is False:
                return
            pvwa_integration.logoff_pvwa(storeParametersClass.pvwaURL, sessionToken)
            aws_services.release_session_on_dynamo(pvwaConnectionnumber, sessionGuid)
            disconnect = True
            instance_processing.create_instance(instanceId, instanceDetails, storeParametersClass, logName, solutionAccountId, eventRegion, eventAccountId, instanceAccountPassword)
        else:
            print('Unknown instance state')
            return


        if not disconnect:
            pvwa_integration.logoff_pvwa(storeParametersClass.pvwaURL, sessionToken)
            aws_services.release_session_on_dynamo(pvwaConnectionnumber, sessionGuid)


    except Exception as e:
        print("Unknown error occurred:{0}".format(e))
        if actionType == 'terminated':
            # put_instance_to_dynamo_table(instanceId, instanceDetails["address"]\
            # , OnBoardStatus.Delete_Failed, str(e), logName)
            aws_services.update_instances_table_status(instanceId, OnBoardStatus.Delete_Failed, str(e))
        elif actionType == 'running':
            aws_services.put_instance_to_dynamo_table(instanceId, instanceDetails["address"], OnBoardStatus.OnBoarded_Failed, str(e),
                                         logName)
        # TODO: Retry mechanism?
        aws_services.release_session_on_dynamo(pvwaConnectionnumber, sessionGuid)
        return
def lambda_handler(event, context):
    logName = context.log_stream_name if context.log_stream_name else "None"
    instanceId, actionType = event.split(";")
    try:
        instanceDetails = aws_services.get_ec2_details(instanceId, context)

        instanceData = aws_services.get_instance_data_from_dynamo_table(
            instanceId)
        if actionType == 'terminated':
            if not instanceData:
                print('Item {0} does not exists on DB'.format(instanceId))
                return None
            else:
                instanceStatus = instanceData["Status"]["S"]
                if instanceStatus == OnBoardStatus.OnBoarded_Failed:
                    print(
                        "Item {0} is in status OnBoard failed, removing from DynamoDB table"
                        .format(instanceId))
                    aws_services.remove_instance_from_dynamo_table(instanceId)
                    return None
        elif actionType == 'running':
            if not instanceDetails[
                    "address"]:  # In case querying AWS return empty address
                print("Retrieving Instance address from AWS failed.")
                return None
            if instanceData:
                instanceStatus = instanceData["Status"]["S"]
                if instanceStatus == OnBoardStatus.OnBoarded:
                    print(
                        'Item: {0}, exists on DB, no need to add it to vault'.
                        format(instanceId))
                    return None
                elif instanceStatus == OnBoardStatus.OnBoarded_Failed:
                    print(
                        "Item {0} exists with status 'OnBoard failed', adding to vault"
                        .format(instanceId))
                else:
                    print('Item {0} does not exists on DB, adding to vault'.
                          format(instanceId))
        else:
            print('Unknown instance state')
            return

        storeParametersClass = aws_services.get_params_from_param_store()
        if not storeParametersClass:
            return
        pvwaConnectionnumber, sessionGuid = aws_services.get_available_session_from_dynamo(
        )
        if not pvwaConnectionnumber:
            return
        sessionToken = pvwa_integration.logon_pvwa(
            storeParametersClass.vaultUsername,
            storeParametersClass.vaultPassword, storeParametersClass.pvwaURL,
            pvwaConnectionnumber)
        if not sessionToken:
            return
        if actionType == 'terminated':
            instance_processing.delete_instance(instanceId, sessionToken,
                                                storeParametersClass,
                                                instanceData, instanceDetails)
        elif actionType == 'running':
            instance_processing.create_instance(instanceId, sessionToken,
                                                instanceDetails,
                                                storeParametersClass, logName)
        else:
            print('Unknown instance state')
            return

        pvwa_integration.logoff_pvwa(storeParametersClass.pvwaURL,
                                     sessionToken)
        aws_services.release_session_on_dynamo(pvwaConnectionnumber,
                                               sessionGuid)

    except Exception as e:
        print("Unknown error occurred:{0}".format(e))
        if actionType == 'terminated':
            # put_instance_to_dynamo_table(instanceId, instanceDetails["address"]\
            # , OnBoardStatus.Delete_Failed, str(e), logName)
            aws_services.update_instances_table_status(
                instanceId, OnBoardStatus.Delete_Failed, str(e))
        elif actionType == 'running':
            aws_services.put_instance_to_dynamo_table(
                instanceId, instanceDetails["address"],
                OnBoardStatus.OnBoarded_Failed, str(e), logName)
        # TODO: Retry mechanism?
        aws_services.release_session_on_dynamo(pvwaConnectionnumber,
                                               sessionGuid)
        return