### 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
/**
     * Runs a fall behind test. In this test, we construct a situation where a follower is paused. While the follower is paused we index
     * more documents that causes soft deletes on the leader, flush them, and run a force merge. This is to set up a situation where the
     * operations will not necessarily be there. With retention leases in place, we would actually expect the operations to be there. After
     * pausing the follower, the specified callback is executed. This gives a test an opportunity to set up assumptions. For example, a test
     * might remove all the retention leases on the leader to set up a situation where the follower will fall behind when it is resumed
     * because the operations will no longer be held on the leader. The specified exceptions callback is invoked after resuming the follower
     * to give a test an opportunity to assert on the resource not found exceptions (either present or not present).
     *
     * @param afterPausingFollower the callback to run after pausing the follower
     * @param exceptionConsumer    the callback to run on a collection of resource not found exceptions after resuming the follower
     * @throws Exception if a checked exception is thrown during the test
     */
    private void runFallBehindTest(
        final CheckedRunnable<Exception> afterPausingFollower,
        final Consumer<Collection<ResourceNotFoundException>> exceptionConsumer
    ) throws Exception {
        final int numberOfPrimaryShards = randomIntBetween(1, 3);
        final Map<String, String> extraSettingsMap = Maps.newMapWithExpectedSize(2);
        extraSettingsMap.put(IndexService.RETENTION_LEASE_SYNC_INTERVAL_SETTING.getKey(), "200ms");
        final String leaderIndexSettings = getIndexSettings(numberOfPrimaryShards, between(0, 1), extraSettingsMap);
        assertAcked(leaderClient().admin().indices().prepareCreate("index1").setSource(leaderIndexSettings, XContentType.JSON));
        ensureLeaderYellow("index1");
        final int numDocs = randomIntBetween(2, 64);
        logger.info("Indexing [{}] docs as first batch", numDocs);
        for (int i = 0; i < numDocs; i++) {
            final String source = Strings.format("{\"f\":%d}", i);
            leaderClient().prepareIndex("index1").setId(Integer.toString(i)).setSource(source, XContentType.JSON).get();
        }
        final PutFollowAction.Request followRequest = putFollow("index1", "index2");