0

我正在使用 python boto 编写 AWS Elasticsearch 快照备份/恢复实现。我能够将 AWS S3 注册为 ES 快照存储库。这是我的创建快照功能的片段。

import boto 
import urllib
from boto.connection import AWSAuthConnection

class ESConnection(AWSAuthConnection):

def __init__(self, region, **kwargs):
  super(ESConnection, self).__init__(**kwargs)
  self._set_auth_region_name(region)
  self._set_auth_service_name("es")

def _required_auth_capability(self):
  return ['hmac-v4']
def create_snapshots(profile, region_name, es_host,total_snapshots_to_keep):
.
.
.
url = "/_snapshot/es_repository/{}?".format(snapshot_name)
flag = urllib.urlencode({'wait_for_completion':'true'})
resp = client.make_request(method='PUT',
    path=urllib.quote("{}{}".format(url,flag)),
    data='{"indices": "' + audit_index_name + '", "ignore_unavailable": true, "include_global_state": false}')

主要问题似乎在上面的片段中,我正在尝试为

{u'status': 400, u'error': {u'root_cause': [{u'reason': u'[es_repository:v4_2017_03_27_snapshot?wait_for_completion=true] 无效的快照名称[v4_2017_03_27_snapshot?wait_for_completion=true],不能包含以下字符 [\, /, *, ?, ", <, >, |, , ,]', u'type': u'invalid_snapshot_name_exception'}], u'type': u'invalid_snapshot_name_exception', u' reason': u'[es_repository:v4_2017_03_27_snapshot?wait_for_completion=true] 无效的快照名称[v4_2017_03_27_snapshot?wait_for_completion=true],不能包含以下字符[\, /, *, ?, ", <, >, |, , , ]'}}

它将我的实际快照名称和 wait_for_completion 标志完全作为快照名称

无效的快照名称 [v4_2017_03_27_snapshot?wait_for_completion=true],不得包含以下字符 [\, /, *, ?, ", <, >, |, , ,]'}}

你能帮我指出我在为弹性搜索构建 url 时做错的地方吗?或者有没有更好的方法来实现这一点?

4

1 回答 1

0

错误信息已经给你答案了。s3 对象名称不支持某些特殊符号。

# the ? ending is wrong, perhaps residual of typo from other language? 
url = "/_snapshot/es_repository/{}?".format(snapshot_name)

# correct path 
url = "/_snapshot/es_repository/{}".format(snapshot_name)

(更新)

当您使用 时curl,您使用的是 RESTful API。这 ”?” 标记是通知 RESTful API 参数在后面。

但是,在您的代码中,您使用client.make_request的是 boto API 的一部分。make_request 模块只接受典型的 S3“路径”AKA 有效的 S3 对象名称。

如果你想模拟相同的 RESTful 路径,那么我建议你使用 pythonrequests和你刚刚构建的路径。IE

import requests
path = urllib.quote("{}{}".format(url,flag))
endpoint_url = "http://.."  # find your snapshot S3 endpoint url and put here   
url = "{}/{}".format(endpoint_url, path) 
data='{"indices": "' + audit_index_name + '", "ignore_unavailable": true, "include_global_state": false}'
rest_resp= requests.post(url, data = data)

由于 boto/boto2 令人困惑的文档和弃用问题,您应该使用 boto3

于 2017-04-06T16:54:22.567 回答