S3 throws 500 when trying to restore snapshot to AWS ES 6.2 [cross-region] - elasticsearch

Trying to restore an v5.3 ES snapshot from S3 to ES 6.2. Snapshot bucket is in us-east-1 and i'm trying to restore it to a Amazon ES cluster in us-west-2. It's a cross-account, cross-region restore operation.
Registered snapshot repository in the us-west-2 ES cluster as below
{
"type": "s3",
"settings": {
"bucket": "valid-bucket-name",
"server_side_encryption": "true",
"endpoint": "s3.amazonaws.com",
"region" : "us-east-1",
"role_arn": "valid-role"
}
}
Got the response as
{
"acknowledged": true
}
But, then when i try to restore a specific snapshot, S3 throws 301
{
"error": {
"root_cause": [
{
"type": "amazon_s3_exception",
"reason": "amazon_s3_exception: The bucket is in this region: us-east-1. Please use this region to retry the request (Service: Amazon S3; Status Code: 301; Error Code: PermanentRedirect; Request ID: D72EFE8A89F76F57; S3 Extended Request ID: in03KW452re297MDp3GQQRFjJhMRXeP4md+FU99CHZ7D4TQKz8PBuSZKoO3+IFd+wAxNApztG5Y=)"
}
],
"type": "amazon_s3_exception",
"reason": "amazon_s3_exception: The bucket is in this region: us-east-1. Please use this region to retry the request (Service: Amazon S3; Status Code: 301; Error Code: PermanentRedirect; Request ID: D72EFE8A89F76F57; S3 Extended Request ID: in03KW452re297MDp3GQQRFjJhMRXeP4md+FU99CHZ7D4TQKz8PBuSZKoO3+IFd+wAxNApztG5Y=)"
},
"status": 500
}
Repository is already configured with region us-east-1. Error message is not useful.
If i just specify the endpoint as #Michael-sqlbot suggested, then it will throw the following error
{
"error": {
"root_cause": [
{
"type": "amazon_s3_exception",
"reason": "amazon_s3_exception: The bucket is in this region: us-east-1. Please use this region to retry the request (Service: Amazon S3; Status Code: 301; Error Code: 301 Moved Permanently; Request ID: CC1853D0EF68B5F7; S3 Extended Request ID: nrbWmI3OiPLdrMcRT6FiOHJineYv6clmSf+GcXtBBwKSzfIEV2gmMZjWEDtyCIRQUg+dM/Vmawg=)"
}
],
"type": "blob_store_exception",
"reason": "Failed to check if blob [master.dat-temp] exists",
"caused_by": {
"type": "amazon_s3_exception",
"reason": "amazon_s3_exception: The bucket is in this region: us-east-1. Please use this region to retry the request (Service: Amazon S3; Status Code: 301; Error Code: 301 Moved Permanently; Request ID: CC1853D0EF68B5F7; S3 Extended Request ID: nrbWmI3OiPLdrMcRT6FiOHJineYv6clmSf+GcXtBBwKSzfIEV2gmMZjWEDtyCIRQUg+dM/Vmawg=)"
}
},
"status": 500
}
Update: I can confirm that it's a region/endpoint related issue with s3-snapshot-plugin. Created another cluster in us-east-1 (same region as that of bucket) and it worked with out any issue.

This seems potentially relevant:
Important
If the S3 bucket is in the us-east-1 region, you need to use "endpoint": "s3.amazonaws.com" instead of "region": "us-east-1". (emphasis added)
https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html

Cannot comment on Michael's answer due to lack of reputation :-)
I tried their suggested workaround to set up a snapshot repo on a new 7.9 cluster in us-west-2 with a bucket located in eu-west-2 and it worked! Doesn't seem to be documented anymore though on Amazon's developer guide. I'll submit feedback to them.
BTW, if you're trying to migrate data from another cluster, don't forget to add "readonly": true to the settings object. This is just to prevent accidentally writing to that repo.

Related

Synapse pipeline - Blob storage event trigger - Pipeline failing with Microsoft.DataTransfer.Common.Shared.HybridDeliveryException

I have a copy activity on storage event trigger. The pipeline gets triggered by a blob getting added to storage (ADLS Gen 2). However, the pipeline's copy activity fails with below error after being run by storage trigger. Pipeline runs successfully using Run/Debug, but fails on StorageEventTrigger (and ManualTrigger).
Operation on target Copy failed: ErrorCode=UnsupportedDataStoreEndpoint,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=The data store endpoint is not supported in 'AzureBlobFS' connector. Error message : 'The domain of this endpoint is not in allow list. Original endpoint: '::redacted::.blob.core.windows.net'',Source=Microsoft.DataTransfer.ClientLibrary,''Type=Microsoft.DataTransfer.SecurityValidation.Exceptions.UrlValidationException,Message=The domain of this endpoint is not in allow list. Original endpoint: '::redacted::.blob.core.windows.net',Source=Microsoft.DataTransfer.SecurityValidation,'
Trigger payload:
{
"topic": "/subscriptions/<redacted>/resourceGroups/<redacted>/providers/Microsoft.Storage/storageAccounts/<redacted>",
"subject": "/blobServices/default/containers/<redacted>/blobs/<redacted>",
"eventType": "Microsoft.Storage.BlobCreated",
"id": "<redacted>",
"data": {
"api": "PutBlob",
"clientRequestId": "<redacted>",
"requestId": "<redacted>",
"eTag": "<redacted>",
"contentType": "text/plain",
"contentLength": 214,
"blobType": "BlockBlob",
"blobUrl": "https://<redacted>.blob.core.windows.net/<redacted>",
"url": "https://<redacted>.blob.core.windows.net/<redacted>",
"sequencer": "<redacted>",
"identity": "$superuser",
"storageDiagnostics": {
"batchId": "<redacted>"
}
},
"dataVersion": "",
"metadataVersion": "1",
"eventTime": "2022-10-05T22:31:48.3346541Z"
}
UPDATE: According to Copy and transform data in Azure Data Lake Storage Gen2 using Azure Data Factory or Azure Synapse Analytics for System-assigned managed identity authentication:
The AzureBlobFS connector must have:
Property-Description-Required
url-Endpoint for Data Lake Storage Gen2 with the pattern of https://.dfs.core.windows.net.-Yes
My trigger payload returns with blob.core.windows.net and seems to interfere with the pipeline activity.
Resolved by creating a new Linked Service to Blob storage acc. Only difference was using account selection method > From Azure Subscription instead of Enter Manually.

AWS Appsync subscription with postman - No Protocol Error

I am using Postman to connect AWS Appsync subscription as per : https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html
with the below config:
{ "payload": { "errors": [ { "message": "NoProtocolError", "errorCode": 400 } ] }, "type": "connection_error" }
The problem occurs due to a missing header:-
Sec-WebSocket-Protocol = graphql-ws
if you get this error in unity use this way;
using System.Net.WebSockets;
var webSocket = new ClientWebSocket();
webSocket.Options.UseDefaultCredentials = false;
webSocket.Options.AddSubProtocol("graphql-ws");

Elasticsearch error resource_already_exists_exception when index doesn't exist for sure

I use random index name for new indices:
async import_index(alias_name, mappings, loadFn) {
const index = `${alias_name}_${+new Date()}`
console.log('creating new index: ', index)
await this.esService.indices.create({
index: index,
body: {
"settings": this.index_settings(),
"mappings": mappings
}
}).then(res => {
console.log('index created: ', index)
}).catch(async (err) => {
console.error(alias_name, ": creating new index", JSON.stringify(err.meta, null, 2))
throw err
});
I believe an index with this name cannot exist, but ES returns me this error
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [brands_1637707367610/bvY5O_NjTm6mU3nQVx7QiA] already exists",
"index_uuid": "bvY5O_NjTm6mU3nQVx7QiA",
"index": "brands_1637707367610"
}
],
"type": "resource_already_exists_exception",
"reason": "index [brands_1637707367610/bvY5O_NjTm6mU3nQVx7QiA] already exists",
"index_uuid": "bvY5O_NjTm6mU3nQVx7QiA",
"index": "brands_1637707367610"
},
"status": 400
}
ES installed in k8s using bitnami helm chart, 3 master nodes running. Client is connected to master service url. My thoughts: client sends a request to all nodes at the same time, but i cannot prove it.
plz help
We have experienced same error with the python client. But from what i see the javascript client is written in similar way.
There is a retry option in the client.
Most likely this is set to true in your case (can be reconfigured). Then you pass a large mapping to this.esService.indices.create. The operation takes too long, times out, then a retry happens, but the index was created on the cluster.
You need to send a larger timeout to elasticsearch index create api (default 30s). And also set the same timeout for the http connection.
Those are 2 separate settings:
Client http connection requestTimeout . Default: 30s
https://github.com/elastic/elasticsearch-js/blob/v7.17.0/lib/Transport.js#L435
https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/7.17/basic-config.html
Serverside timeout via Create Index API. Default: 30s
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/indices-create-index.html
this.esService = new Client({
// ....
maxRetries: 5,
requestTimeout: 60000 // time in ms
})
// ....
tnis.esService.indices.create({
index: index,
body: {
"settings": this.index_settings(),
"mappings": mappings
},
timeout: "60s" // elasticsearch timestring
})

Unable to restore snapshot from URL repository with basic authentication

Problem:
I'm trying to create snapshot on ES instance ES1, and restore to another instance ES2. It fails to restore when the remote URL requires basic authentication.
ES version: 6.5.4
Success and failure cases:
Success case: When the website exposing the ES1 repository folder is open to the internet (no authentication), the listing/restore works fine. For example when the repo URL is "http://snapshots.example-server.com"
Failure case: When I add basic authentication to the same URL, it doesn't work. For example when the repo URL is: "http://username:password#snapshots.example-server.com"
When I try to list snapshots in the URL repository with basic authentication, the error I get is:
{
"error": {
"root_cause": [
{
"type": "repository_exception",
"reason": "[remote-repo] could not read repository data from index blob"
}
],
"type": "repository_exception",
"reason": "[remote-repo] could not read repository data from index blob",
"caused_by": {
"type": "i_o_exception",
"reason": "Server returned HTTP response code: 401 for URL: http://username:password#snapshots.example-server.com/index.latest"
}
},
"status": 500
}
The Setup:
Setting up ES1:
Step 1: Modify config file:
path.repo: ["/path/to/es1_repo"]
Step 2: Creating the repo:
PUT /_snapshot/es1_repo
{
"type": "fs",
"settings": {
"location": "/path/to/es1_repo"
}
}
Step 3: Making the repository path accessible from internet:
I have setup an nginx server on the ES1 machine, to expose "/path/to/es1_repo” directory listing, let's say at: http://snapshots.example-server.com. It has basic authentication enabled. You could, for example, access the repo as http://username:password#snapshots.example-server.com and you would see the directory listing.
Step 4: Create the snapshot:
PUT /_snapshot/es1_repo/snapshot_1?wait_for_completion=true
{
"indices": "the_index_name",
"ignore_unavailable": true,
"include_global_state": false
}
Setting up ES2:
Step 5: Add to elastic config:
repositories.url.allowed_urls: "http://username:password#snapshots.example-server.com"
Step 6: Register repo
PUT _snapshot/remote-repo
{
"type": "url",
"settings": {
"url": "http://username:password#snapshots.example-server.com"
}
}
Step 7: Check if the snapshot is accessible:
GET _snapshot/remote-repo/_all
At this step the error pasted at the top appears. If I disable basic authentication, it works fine.
What could be the issue here?
You should make these:
Add to whitelist the repository in elasticsearch.yaml or docker environment
repositories.url.allowed_urls: "http://snapshots.example-server.com"
Create the snapshots repository
PUT _snapshot/remote-repo
{
"type": "url",
"settings": {
"url": "http://snapshots.example-server.com",
"client": "your_client",
}
}
Add username and password to the Elasticsearch keystore
bin/elasticsearch-keystore add url.client.your_client.username
bin/elasticsearch-keystore add url.client.your_client.password

Update Azure Event Grid function subscription with dead-letter storage

I have successfully created an event trigger on storage blob creation, on a storage account called receivingtestwesteurope, under resource group omni-test, which is received via a function called ValidateMetadata. I created this via the portal GUI. However I now want to add deadletter/retry policies, which can only be done via the CLI.
The working trigger is like this:
{
"destination": {
"endpointBaseUrl": "https://omnireceivingprocesstest.azurewebsites.net/admin/extensions/EventGridExtensionConfig",
"endpointType": "WebHook",
"endpointUrl": null
},
"filter": {
"includedEventTypes": [
"Microsoft.Storage.BlobCreated"
],
"isSubjectCaseSensitive": null,
"subjectBeginsWith": "/blobServices/default/containers/snapshots/blobs/",
"subjectEndsWith": ".png"
},
"id": "/subscriptions/fa6409ab-1234-1234-1234-85dd2b3ceab4/resourceGroups/omni-test/providers/Microsoft.Storage/StorageAccounts/receivingtestwesteurope/providers/Microsoft.EventGrid/eventSubscriptions/png",
"labels": [
""
],
"name": "png",
"provisioningState": "Succeeded",
"resourceGroup": "omni-test",
"topic": "/subscriptions/fa6409ab-1234-1234-1234-85dd2b3ceab4/resourceGroups/omni-test/providers/microsoft.storage/storageaccounts/receivingtestwesteurope",
"type": "Microsoft.EventGrid/eventSubscriptions"
}
First I thought I could update the existing event with a deadletter queue:
az eventgrid event-subscription update --name png --deadletter-endpoint receivingtestwesteurope/blobServices/default/containers/eventgrid
Which returns:
az: error: unrecognized arguments: --deadletter-endpoint
receivingtestwesteurope/blobServices/default/containers/eventgrid
Then I tried via REST Patch:
https://learn.microsoft.com/en-us/rest/api/eventgrid/eventsubscriptions/update
scope: /subscriptions/fa6409ab-1234-1234-1234-85dd2b3ceab4/resourceGroups/omni-test/providers/microsoft.storage/storageaccounts/receivingtestwesteurope
eventSubscriptionName: png
api-version: 2018-05-01-preview
Body:
"deadletterdestination": {
"endpointType": "StorageBlob",
"properties": {
"blobContainerName": "eventgrid",
"resourceId": "/subscriptions/fa6409ab-1234-1234-1234-85dd2b3ceab4/resourceGroups/omni-test/providers/microsoft.storage/storageaccounts/receivingtestwesteurope"
}}
Which returns
"Model state is invalid."
===================
Final working solution:
{
"deadletterdestination": {
"endpointType": "StorageBlob",
"properties": {
"blobContainerName": "eventgrid",
"resourceId": "/subscriptions/fa6409ab-1234-1234-1234-85dd2b3ceab4/resourceGroups/omni-test/providers/microsoft.storage/storageaccounts/receivingtestwesteurope"
}
}
}
have a look at Manage Event Grid delivery settings, where in details is described turning-on a dead-lettering. Note, you have to install an eventgrid extension
az extension add --name eventgrid
also, you can use a REST API for updating your event subscription for dead-lettering.
besides that, I have just released my tinny tool Azure Event Grid Tester for helping with an Azure Event Grid model on the local machine.
Update:
The following is a deadletterdestination property:
"deadletterdestination": {
"endpointType": "StorageBlob",
"properties": {
"blobContainerName": "{containerName}",
"resourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resgroup}/providers/Microsoft.Storage/storageAccounts/{storageAccount}"
}
}
you can use the Event Subscriptions - Update (REST API PATCH) with the above property. Note, that the api-version=2018-05-01-preview must be used.

Resources