### Description

It is impossible to create a follower index with a `$` character in its name (please note, it is possible to create a regular index with `$` in its name).

This could be reproduced by rest request:
```
PUT /my-index/_ccr/follow
{
    "remote_cluster": "my-remote-cluster",
    "leader_index": "my-index$follower"
}
```

or `CcrIntegTestCase`:

```
    public void testFollowIndex() throws Exception {
        assertAcked(leaderClient().admin().indices().prepareCreate("my$index"));
        setupRemoteCluster();
        final PutFollowAction.Request followRequest = putFollow("my$index", "my$index");
        followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
    }
```

This is happening as during initial follow phase we restore the leader cluster from the remote using a snapshot restore.
Corresponding request is created with index name added to `RestoreSnapshotRequest#renamePattern` (regexp) without escaping `$`.

x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/IndexFollowingIT.java
);
        assertAcked(leaderClient().admin().indices().updateSettings(updateSettingsRequest).actionGet());
        OpenIndexRequest openIndexRequest = new OpenIndexRequest("leader");
        assertAcked(leaderClient().admin().indices().open(openIndexRequest).actionGet());
        ensureLeaderGreen("leader");
        PutMappingRequest putMappingRequest = new PutMappingRequest("leader");
        putMappingRequest.source("new_field", "type=text,analyzer=my_analyzer");
        assertAcked(leaderClient().admin().indices().putMapping(putMappingRequest).actionGet());
        final int secondBatchNumDocs = randomIntBetween(2, 64);
        for (long i = firstBatchNumDocs; i < firstBatchNumDocs + secondBatchNumDocs; i++) {
            final String source = Strings.format("{\"new_field\":\"value %d\"}", i);
            leaderClient().prepareIndex("leader").setSource(source, XContentType.JSON).get();
        }
        assertBusy(() -> {
            assertThat(getFollowTaskSettingsVersion("follower"), equalTo(4L));
            assertThat(getFollowTaskMappingVersion("follower"), equalTo(2L));
            GetSettingsRequest getSettingsRequest = new GetSettingsRequest();
            getSettingsRequest.indices("follower");
            GetSettingsResponse getSettingsResponse = followerClient().admin().indices().getSettings(getSettingsRequest).actionGet();
            assertThat(getSettingsResponse.getSetting("follower", "index.analysis.analyzer.my_analyzer.type"), equalTo("custom"));
            assertThat(getSettingsResponse.getSetting("follower", "index.analysis.analyzer.my_analyzer.tokenizer"), equalTo("keyword"));
            GetMappingsRequest getMappingsRequest = new GetMappingsRequest();
            getMappingsRequest.indices("follower");
            GetMappingsResponse getMappingsResponse = followerClient().admin().indices().getMappings(getMappingsRequest).actionGet();
            MappingMetadata mappingMetadata = getMappingsResponse.getMappings().get("follower");
            assertThat(XContentMapValues.extractValue("properties.new_field.type", mappingMetadata.sourceAsMap()), equalTo("text"));
            assertThat(
                XContentMapValues.extractValue("properties.new_field.analyzer", mappingMetadata.sourceAsMap()),
                equalTo("my_analyzer")
            );