Пример #1
0
 def test_do_action_raise_snap_in_progress(self):
     client = Mock()
     client.indices.get_settings.return_value = testvars.settings_one
     client.cluster.state.return_value = testvars.clu_state_one
     client.indices.stats.return_value = testvars.stats_one
     client.snapshot.get_repository.return_value = testvars.test_repo
     client.snapshot.get.return_value = testvars.snapshots
     client.snapshot.create.return_value = None
     client.snapshot.status.return_value = testvars.snap_running
     client.snapshot.verify_repository.return_value = testvars.verified_nodes
     ilo = curator.IndexList(client)
     so = curator.Snapshot(ilo,
                           repository=testvars.repo_name,
                           name=testvars.snap_name)
     self.assertRaises(curator.SnapshotInProgress, so.do_action)
Пример #2
0
 def test_do_dry_run(self):
     client = Mock()
     client.indices.get_settings.return_value = testvars.settings_one
     client.cluster.state.return_value = testvars.clu_state_one
     client.indices.stats.return_value = testvars.stats_one
     client.snapshot.get_repository.return_value = testvars.test_repo
     client.snapshot.get.return_value = testvars.snapshots
     client.snapshot.create.return_value = None
     client.snapshot.status.return_value = testvars.nosnap_running
     client.snapshot.verify_repository.return_value = testvars.verified_nodes
     ilo = curator.IndexList(client)
     so = curator.Snapshot(ilo,
                           repository=testvars.repo_name,
                           name=testvars.snap_name)
     self.assertIsNone(so.do_dry_run())
Пример #3
0
 def test_do_action_raise_on_failure(self):
     client = Mock()
     client.info.return_value = {'version': {'number': '5.0.0'} }
     client.indices.get_settings.return_value = testvars.settings_one
     client.cluster.state.return_value = testvars.clu_state_one
     client.indices.stats.return_value = testvars.stats_one
     client.snapshot.get_repository.return_value = testvars.test_repo
     client.snapshot.get.return_value = testvars.snapshots
     client.snapshot.create.return_value = None
     client.snapshot.create.side_effect = testvars.fake_fail
     client.snapshot.status.return_value = testvars.nosnap_running
     client.snapshot.verify_repository.return_value = testvars.verified_nodes
     ilo = curator.IndexList(client)
     so = curator.Snapshot(ilo, repository=testvars.repo_name,
         name=testvars.snap_name)
     self.assertRaises(curator.FailedExecution, so.do_action)
Пример #4
0
 def test_do_action_success(self):
     client = Mock()
     client.info.return_value = {'version': {'number': '5.0.0'} }
     client.indices.get_settings.return_value = testvars.settings_one
     client.cluster.state.return_value = testvars.clu_state_one
     client.indices.stats.return_value = testvars.stats_one
     client.snapshot.get_repository.return_value = testvars.test_repo
     client.snapshot.get.return_value = testvars.snapshots
     client.snapshot.create.return_value = testvars.generic_task
     client.tasks.get.return_value = testvars.completed_task
     client.snapshot.status.return_value = testvars.nosnap_running
     client.snapshot.verify_repository.return_value = testvars.verified_nodes
     ilo = curator.IndexList(client)
     so = curator.Snapshot(ilo, repository=testvars.repo_name,
         name=testvars.snap_name)
     self.assertIsNone(so.do_action())
Пример #5
0
 def test_deletesnapshot(self):
     def add_docs(idx):
         for i in ["1", "2", "3"]:
             self.client.create(
                 index=idx, doc_type='log',
                 body={"doc" + i :'TEST DOCUMENT'},
             )
             # This should force each doc to be in its own segment.
             self.client.indices.flush(index=idx, force=True)
     ### Create snapshots to delete and verify them
     self.create_repository()
     timestamps = []
     for i in range(1,4):
         add_docs('my_index{0}'.format(i))
         ilo = curator.IndexList(self.client)
         snap = curator.Snapshot(ilo, repository=self.args['repository'],
             name='curator-%Y%m%d%H%M%S'
         )
         snap.do_action()
         snapshot = curator.get_snapshot(
                     self.client, self.args['repository'], '_all'
                    )
         self.assertEqual(i, len(snapshot['snapshots']))
         time.sleep(1.0)
         timestamps.append(int(time.time()))
         time.sleep(1.0)
     ### Setup the actual delete
     self.write_config(
         self.args['configfile'], testvars.client_config.format(host, port))
     self.write_config(self.args['actionfile'],
         testvars.delete_snap_proto.format(
             self.args['repository'], 'age', 'creation_date', 'older', ' ',
             'seconds', '0', timestamps[0]
         )
     )
     test = clicktest.CliRunner()
     result = test.invoke(
                 curator.cli,
                 [
                     '--config', self.args['configfile'],
                     self.args['actionfile']
                 ],
                 )
     snapshot = curator.get_snapshot(
                 self.client, self.args['repository'], '_all'
                )
     self.assertEqual(2, len(snapshot['snapshots']))
Пример #6
0
def lambda_handler(event, context):
    """ Prior to running snapshots, we're checking if we can connect,
    and if for the current status of the cluster and the repository.
    """
    try:
        health = es.cat.health().split(" ")[3]
        repo = es.cat.repositories()
        if health == 'red':
            slackpost('danger', 'Cluster status is RED! Investigate ASAP!! ')
            exit
        if repo is None:
            slackpost(
                'warning',
                'Missing repository for snapshot.'
                'Trying to recreate the repository...')
            try:
                es.snapshot.create_repository(
                    repository='s3', body=repository_body)
                es.snapshot.get_repository('s3')
                slackpost('good', 'Successfully re-created the repository.')
            except exceptions.NotFoundError as e:
                slackpost(
                    'danger', 'Failed to create the repository. Please check!')
        # Create the snapshot
        ilo = curator.IndexList(es)
        create_snapshot = curator.Snapshot(ilo=ilo,
                                           repository='s3',
                                           name=snapshot_name)
        create_snapshot.do_action()
        create_snapshot_status = create_snapshot.get_state()

        if create_snapshot_status == 'SUCCESS':
            msg = "Successfully created new snapshot:\n" + snapshot_name
            color = 'good'
            slackpost(color, msg)
        else:
            msg = "Failed to create new snapshot"
            color = 'danger'
            slackpost(color, msg)

        # Deleting old indices
        ilo.filter_by_age(source='creation_date', direction='older',
                          unit='months', unit_count=1)
        curator.DeleteIndices(ilo)
    except exceptions.ConnectionError as e:
        slackpost('danger', e)
 def test_deletesnapshot(self):
     ### Create snapshots to delete and verify them
     self.create_repository()
     timestamps = []
     for i in range(1,4):
         self.add_docs('my_index{0}'.format(i))
         ilo = curator.IndexList(self.client)
         snap = curator.Snapshot(ilo, repository=self.args['repository'],
             name='curator-%Y%m%d%H%M%S', wait_interval=0.5
         )
         snap.do_action()
         snapshot = curator.get_snapshot(
                     self.client, self.args['repository'], '_all'
                    )
         self.assertEqual(i, len(snapshot['snapshots']))
         time.sleep(1.0)
         timestamps.append(int(time.time()))
         time.sleep(1.0)
     ### Setup the actual delete
     self.write_config(
         self.args['configfile'], testvars.client_config.format(host, port))
     self.write_config(self.args['actionfile'],
         testvars.delete_snap_proto.format(
             self.args['repository'], 'age', 'creation_date', 'older', ' ',
             'seconds', '0', timestamps[0]
         )
     )
     test = clicktest.CliRunner()
     result = test.invoke(
                 curator.cli,
                 [
                     '--config', self.args['configfile'],
                     self.args['actionfile']
                 ],
                 )
     snapshot = curator.get_snapshot(
                 self.client, self.args['repository'], '_all'
                )
     self.assertEqual(2, len(snapshot['snapshots']))
Пример #8
0
 def test_deletesnapshot(self):
     ### Create snapshots to delete and verify them
     self.create_repository()
     timestamps = []
     for i in range(1, 4):
         self.add_docs('my_index{0}'.format(i))
         ilo = curator.IndexList(self.client)
         snap = curator.Snapshot(ilo,
                                 repository=self.args['repository'],
                                 name='curator-%Y%m%d%H%M%S',
                                 wait_interval=0.5)
         snap.do_action()
         snapshot = curator.get_snapshot(self.client,
                                         self.args['repository'], '_all')
         self.assertEqual(i, len(snapshot['snapshots']))
         time.sleep(1.0)
         timestamps.append(int(time.time()))
         time.sleep(1.0)
     ### Setup the actual delete
     args = self.get_runner_args()
     args += [
         '--config',
         self.args['configfile'],
         'delete-snapshots',
         '--repository',
         self.args['repository'],
         '--filter_list',
         '{"filtertype":"age","source":"creation_date","direction":"older","unit":"seconds","unit_count":0,"epoch":'
         + str(timestamps[0]) + '}',
     ]
     self.assertEqual(
         0,
         self.run_subprocess(
             args, logname='TestCLIDeleteSnapshots.test_deletesnapshot'))
     snapshot = curator.get_snapshot(self.client, self.args['repository'],
                                     '_all')
     self.assertEqual(2, len(snapshot['snapshots']))
Пример #9
0
def lambda_handler(event, context):
    # Build the Elasticsearch client.
    es = Elasticsearch(hosts=[{
        'host': host,
        'port': 443
    }],
                       http_auth=awsauth,
                       use_ssl=True,
                       verify_certs=True,
                       connection_class=RequestsHttpConnection)

    #print(es.info())
    index_list = curator.IndexList(es)

    # Do index deletion first
    index_list.filter_by_age(source='name',
                             direction='older',
                             timestring='%Y.%m.%d',
                             unit='days',
                             unit_count=index_rentention_days)
    if index_list.indices:
        print("Found %s indices to delete " % len(index_list.indices))
        print(index_list.indices)
        try:
            curator.DeleteIndices(index_list).do_action()
        except (curator.exceptions.FailedExecution) as e:
            print(e)

    # Snapshots next
    # QA first
    # Filters by age, anything with a time stamp older than delete_index_day days in the index name.
    index_list = curator.IndexList(es)
    index_list.filter_by_regex(kind='prefix', value='qa', exclude=False)
    if index_list.indices:
        index_list.filter_by_age(source='name',
                                 direction='older',
                                 timestring='%Y.%m.%d',
                                 unit='days',
                                 unit_count=snapshot_index_days)
        if index_list.indices:
            print("Found %s indices to snapshot " % len(index_list.indices))
            print(index_list.indices)
            try:
                curator.Snapshot(index_list,
                                 repository='my-es-snapshot-repo',
                                 name='qa-%Y%m%d%H%M%S',
                                 ignore_unavailable=True,
                                 include_global_state=False,
                                 partial=True,
                                 wait_for_completion=False,
                                 wait_interval=10,
                                 max_wait=-1,
                                 skip_repo_fs_check=True).do_action()
            except (curator.exceptions.SnapshotInProgress,
                    curator.exceptions.FailedExecution) as e:
                print(e)

    # Do STAGE now
    index_list = curator.IndexList(es)
    index_list.filter_by_regex(kind='prefix', value='stage', exclude=False)
    if index_list.indices:
        index_list.filter_by_age(source='name',
                                 direction='older',
                                 timestring='%Y.%m.%d',
                                 unit='days',
                                 unit_count=snapshot_index_days)
        if index_list.indices:
            print("Found %s indices to snapshot " % len(index_list.indices))
            print(index_list.indices)
            try:
                curator.Snapshot(index_list,
                                 repository='my-es-snapshot-repo',
                                 name='stage-%Y%m%d%H%M%S',
                                 ignore_unavailable=True,
                                 include_global_state=False,
                                 partial=True,
                                 wait_for_completion=False,
                                 wait_interval=10,
                                 max_wait=-1,
                                 skip_repo_fs_check=True).do_action()
            except (curator.exceptions.SnapshotInProgress,
                    curator.exceptions.FailedExecution) as e:
                print(e)

    # Do PROD now
    index_list = curator.IndexList(es)
    index_list.filter_by_regex(kind='prefix', value='prod', exclude=False)
    if index_list.indices:
        index_list.filter_by_age(source='name',
                                 direction='older',
                                 timestring='%Y.%m.%d',
                                 unit='days',
                                 unit_count=snapshot_index_days)
        if index_list.indices:
            print("Found %s indices to snapshot " % len(index_list.indices))
            print(index_list.indices)
            try:
                curator.Snapshot(index_list,
                                 repository='my-es-snapshot-repo',
                                 name='prod-%Y%m%d%H%M%S',
                                 ignore_unavailable=True,
                                 include_global_state=False,
                                 partial=True,
                                 wait_for_completion=False,
                                 wait_interval=10,
                                 max_wait=-1,
                                 skip_repo_fs_check=True).do_action()
            except (curator.exceptions.SnapshotInProgress,
                    curator.exceptions.FailedExecution) as e:
                print(e)

    # Now delete old snapshots
    snapshot_list = curator.SnapshotList(es, repository='my-es-snapshot-repo')
    if snapshot_list.snapshots:
        snapshot_list.filter_by_age(source='creation_date',
                                    direction='older',
                                    timestring='%Y.%m.%d',
                                    unit='days',
                                    unit_count=snapshot_rentention_days)
        if snapshot_list.snapshots:
            try:
                curator.DeleteSnapshots(snapshot_list,
                                        retry_interval=10,
                                        retry_count=3).do_action()
            except (curator.exceptions.SnapshotInProgress,
                    curator.exceptions.NoSnapshots,
                    curator.exceptions.FailedExecution) as e:
                print(e)
Пример #10
0
def lambda_handler(event, dummy_contest):
    """
        this methode is called by lambda.
        event must contain:
        * es_endpoint: elasticsearch endpoint
        * delete_older_days: delete indices older than number (in days)
        * snapshot_older_days: snapshot indices older than number (in days)
        * repository: name of the repository
        * backup_bucket: name of the bucket to store backup in
        * backup_path: path in the bucket to store backup
        this function will exit when elasticsearch take more than 60 sec,
        to avoid having that running for long.
        The next run will continue, but this has to be run multiple time a day
    """
    logging.warning(event)

    logging.warning("connecting to elasticsearch")
    client = elasticsearch.Elasticsearch([event['es_endpoint']], timeout=120)
    curator.utils.override_timeout(client, 120)

    logging.warning("Checking for repositories")
    repo_dict = curator.utils.get_repository(
        client,
        repository=event["repository"]
    )
    if not repo_dict:
        repo_setting = {
            "repository": event["repository"],
            "client": client,
            "repo_type": "s3",
            "chunk_size": "100m",
            "bucket": event["backup_bucket"],
            "base_path": event["backup_path"]
        }
        if curator.utils.create_repository(**repo_setting):
            return "Snapshot's repository setup Failed"

    logging.warning("Prepare merging indices")
    # optimize/force merge
    ilo = curator.IndexList(client)
    ilo.filter_by_age(
        source='name',
        direction='older',
        timestring='%Y.%m.%d',
        unit='days',
        unit_count=1
    )
    fm_indices = curator.ForceMerge(ilo, max_num_segments=1)
    try:
        logging.warning("Merging indices %s", ilo.working_list())
        fm_indices.do_action()
    except elasticsearch.ConnectionTimeout:
        # exit on timeout make sure it's not running for nothing, next run will
        # continue
        logging.warning("Merge timeout, exiting")
        return "Wait for Merge"

    logging.warning("Prepare snapshoting indices")
    # snapshot
    ils = curator.IndexList(client)
    ils.filter_by_regex(kind='prefix', value='logs-')
    ils.filter_by_age(
        source='name',
        direction='older',
        timestring='%Y.%m.%d',
        unit='days',
        unit_count=int(event["snapshot_older_days"])
    )
    if len(ils.indices) > 0:
        snap_indices = curator.Snapshot(
            ils,
            name="logs_%Y-%m-%d_%H:%M:%S",
            repository=event["repository"],
            wait_for_completion=True
        )
        try:
            logging.warning("Snapshoting indices %s", ils.working_list())
            snap_indices.do_action()
        except curator.SnapshotInProgress:
            # exit on timeout make sure it's not running for nothing, next run
            # will continue
            logging.warning("Snapshot in progress")
            return "Wait for Snapshots"
        except elasticsearch.ConnectionTimeout:
            # exit on timeout make sure it's not running for nothing, next run
            # will continue
            logging.warning("Snapshot timeout, exiting")
            return "Wait for Snapshots"

    logging.warning("Prepare deleting indices")

    free_space = client.cluster.stats()["nodes"]["fs"]["free_in_bytes"] / 1024
    size_unit = {
        'M': 1024.0,
        'G': 1048576.0,
        'T': 1073741824.0
    }
    current_unit = size_unit[event['delete_when_free_space_remaining'][-1]]
    free_space /= current_unit
    size_needed = float(event['delete_when_free_space_remaining'][:-1])
    if free_space > size_needed:
        logging.warning("Enough space remaining, no need to delete indices")
        return
    extra_space = free_space - size_needed
    ild = curator.IndexList(client)
    ild.filter_by_regex(kind='prefix', value='logs-')
    ild.filter_by_age(
        source='name',
        direction='older',
        timestring='%Y.%m.%d',
        unit='days',
        unit_count=2
    )

    def atoi(text):
        """ transformt str to int"""
        return int(text) if text.isdigit() else text

    def natural_keys(text):
        """ transformt str to int and remove non int"""
        return [atoi(c) for c in re.split(r'(\d+)', text)]

    sorted_indices = sorted(ild.indices, key=natural_keys, reverse=True)
    stats = client.indices.stats(index=','.join(sorted_indices))

    size_indices = {}
    for indice in sorted_indices:
        size = stats["indices"][indice]["total"]["store"]["size_in_bytes"]
        size_indices[indice] = size / (current_unit * 1024)

    while extra_space < 0:
        indice_to_remove = sorted_indices.pop()
        try:
            logging.warning("Deleting indices %s", indice_to_remove)
            client.indices.delete(
                index=indice_to_remove,
                params={"timeout": "5s"}
            )
        except elasticsearch.ConnectionTimeout:
            # exit on timeout make sure it's not running for nothing, next
            # run will continue
            logging.warning("Delete timeout, exiting")
            return "Wait for Delete"
        extra_space += size_indices[indice_to_remove]
def lambda_handler(event, context):

    now = datetime.now()
    snapshot_prefix = 'automatic-'
    snapshot_name = snapshot_prefix + now.strftime("%Y%m%d%H%M%S")

    # Build the Elasticsearch client.
    es = Elasticsearch(
        hosts=[{
            'host': host,
            'port': 443
        }],
        http_auth=awsauth,
        use_ssl=True,
        verify_certs=True,
        connection_class=RequestsHttpConnection,
        # Deleting snapshots can take a while, so keep the connection open for long enough to get a response.
        timeout=120)

    # REGISTER
    try:
        payload = {
            "type": "s3",
            "settings": {
                "bucket": bucket,
                "region": region,
                "role_arn": role_arn
            }
        }

        es.snapshot.create_repository(repository_name, json.dumps(payload))

    except (ElasticsearchException) as e:
        print(e)
        raise

    # DELETE
    try:
        snapshot_list = curator.SnapshotList(es, repository=repository_name)
        snapshot_list.filter_by_regex(kind='prefix', value=snapshot_prefix)
        snapshot_list.filter_by_age(source='creation_date',
                                    direction='older',
                                    unit='days',
                                    unit_count=int(retention))

        # Delete the old snapshots.
        curator.DeleteSnapshots(snapshot_list,
                                retry_interval=30,
                                retry_count=3).do_action()

    except (curator.exceptions.NoSnapshots) as e:
        # This is fine
        print(e)
    except (curator.exceptions.SnapshotInProgress,
            curator.exceptions.FailedExecution) as e:
        print(e)
        raise

    # CREATE
    try:
        index_list = curator.IndexList(es)

        # Take a new snapshot. This operation can take a while, so we don't want to wait for it to complete.
        curator.Snapshot(index_list,
                         repository=repository_name,
                         name=snapshot_name,
                         wait_for_completion=False).do_action()

    except (curator.exceptions.SnapshotInProgress,
            curator.exceptions.FailedExecution) as e:
        print(e)
        raise