### 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
final int firstBatchNumDocs = randomIntBetween(2, 64);
        logger.info("Indexing [{}] docs as first batch", firstBatchNumDocs);
        for (int i = 0; i < firstBatchNumDocs; i++) {
            leaderClient().prepareIndex("index1").setId(Integer.toString(i)).setSource("f", i).get();
        }
        AtomicBoolean isRunning = new AtomicBoolean(true);
        
        int numFields = between(10, 20);
        Thread thread = new Thread(() -> {
            int numDocs = between(10, 200);
            for (int i = 0; i < numDocs; i++) {
                if (isRunning.get() == false) {
                    break;
                }
                final String field = "f-" + between(1, numFields);
                leaderClient().prepareIndex("index1").setSource(field, between(0, 1000)).get();
                if (rarely()) {
                    leaderClient().admin().indices().prepareFlush("index1").setWaitIfOngoing(false).setForce(false).get();
                }
            }
        });
        thread.start();
        final PutFollowAction.Request followRequest = putFollow("index1", "index2", ActiveShardCount.NONE);
        followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
        ensureFollowerGreen("index2");
        for (int i = 0; i < firstBatchNumDocs; i++) {
            assertBusy(assertExpectedDocumentRunnable(i), 1, TimeUnit.MINUTES);
        }
        final int secondBatchNumDocs = randomIntBetween(2, 64);
        logger.info("Indexing [{}] docs as second batch", secondBatchNumDocs);