From e1717df0ac814caa26d3ecba54e8bc95a905628a Mon Sep 17 00:00:00 2001
From: Jason Tedor <jason@tedor.me>
Date: Sat, 22 Dec 2018 07:21:49 -0500
Subject: [PATCH] Package ingest-geoip as a module (#36898)

This commit moves ingest-geoip from being a plugin to being a module
that is packaged with Elasticsearch distributions.
---
 distribution/docker/build.gradle              |  2 --
 distribution/docker/src/docker/Dockerfile     |  3 +-
 .../plugins/InstallPluginCommand.java         | 10 +++++++
 .../plugins/RemovePluginCommand.java          |  8 ++++++
 .../plugins/InstallPluginCommandTests.java    | 11 ++++++++
 .../plugins/RemovePluginCommandTests.java     | 28 +++++++++++++++++++
 docs/plugins/ingest.asciidoc                  | 10 -------
 docs/reference/cat/plugins.asciidoc           |  1 -
 docs/reference/cluster/nodes-info.asciidoc    |  7 -----
 docs/reference/cluster/stats.asciidoc         |  7 -----
 docs/reference/ingest/ingest-node.asciidoc    |  5 ++--
 .../ingest/processors/geoip.asciidoc}         | 13 ++++-----
 .../ingest-geoip/build.gradle                 |  0
 .../licenses/geoip2-2.9.0.jar.sha1            |  0
 .../ingest-geoip/licenses/geoip2-LICENSE.txt  |  0
 .../ingest-geoip/licenses/geoip2-NOTICE.txt   |  0
 .../jackson-annotations-2.8.11.jar.sha1       |  0
 .../licenses/jackson-annotations-LICENSE      |  0
 .../licenses/jackson-annotations-NOTICE       |  0
 .../licenses/jackson-databind-2.8.11.jar.sha1 |  0
 .../licenses/jackson-databind-LICENSE         |  0
 .../licenses/jackson-databind-NOTICE          |  0
 .../licenses/maxmind-db-1.2.2.jar.sha1        |  0
 .../licenses/maxmind-db-LICENSE.txt           |  0
 .../licenses/maxmind-db-NOTICE.txt            |  0
 .../geoip/DatabaseReaderLazyLoader.java       |  0
 .../ingest/geoip/GeoIpProcessor.java          |  0
 .../ingest/geoip/IngestGeoIpPlugin.java       |  2 +-
 .../plugin-metadata/plugin-security.policy    |  0
 .../geoip/GeoIpProcessorFactoryTests.java     |  0
 .../GeoIpProcessorNonIngestNodeTests.java     |  0
 .../ingest/geoip/GeoIpProcessorTests.java     |  0
 .../IngestGeoIpClientYamlTestSuiteIT.java     |  1 -
 .../ingest/geoip/IngestGeoIpPluginTests.java  |  0
 .../test/ingest_geoip/10_basic.yml            |  4 +--
 .../test/ingest_geoip/20_geoip_processor.yml  |  0
 .../build.gradle                              |  6 +---
 .../tests/module_and_plugin_test_cases.bash   | 12 +++-----
 38 files changed, 74 insertions(+), 56 deletions(-)
 rename docs/{plugins/ingest-geoip.asciidoc => reference/ingest/processors/geoip.asciidoc} (96%)
 rename {plugins => modules}/ingest-geoip/build.gradle (100%)
 rename {plugins => modules}/ingest-geoip/licenses/geoip2-2.9.0.jar.sha1 (100%)
 rename {plugins => modules}/ingest-geoip/licenses/geoip2-LICENSE.txt (100%)
 rename {plugins => modules}/ingest-geoip/licenses/geoip2-NOTICE.txt (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-annotations-2.8.11.jar.sha1 (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-annotations-LICENSE (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-annotations-NOTICE (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-databind-2.8.11.jar.sha1 (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-databind-LICENSE (100%)
 rename {plugins => modules}/ingest-geoip/licenses/jackson-databind-NOTICE (100%)
 rename {plugins => modules}/ingest-geoip/licenses/maxmind-db-1.2.2.jar.sha1 (100%)
 rename {plugins => modules}/ingest-geoip/licenses/maxmind-db-LICENSE.txt (100%)
 rename {plugins => modules}/ingest-geoip/licenses/maxmind-db-NOTICE.txt (100%)
 rename {plugins => modules}/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java (100%)
 rename {plugins => modules}/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpProcessor.java (100%)
 rename {plugins => modules}/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java (99%)
 rename {plugins => modules}/ingest-geoip/src/main/plugin-metadata/plugin-security.policy (100%)
 rename {plugins => modules}/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorFactoryTests.java (100%)
 rename {plugins => modules}/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorNonIngestNodeTests.java (100%)
 rename {plugins => modules}/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorTests.java (100%)
 rename {plugins => modules}/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java (99%)
 rename {plugins => modules}/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpPluginTests.java (100%)
 rename {plugins => modules}/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml (74%)
 rename {plugins => modules}/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/20_geoip_processor.yml (100%)

diff --git a/distribution/docker/build.gradle b/distribution/docker/build.gradle
index 84a80815ac2..d88dec5caea 100644
--- a/distribution/docker/build.gradle
+++ b/distribution/docker/build.gradle
@@ -12,7 +12,6 @@ configurations {
 }
 
 dependencies {
-  dockerPlugins project(path: ":plugins:ingest-geoip", configuration: 'zip')
   dockerPlugins project(path: ":plugins:ingest-user-agent", configuration: 'zip')
   dockerSource project(path: ":distribution:archives:tar")
   ossDockerSource project(path: ":distribution:archives:oss-tar")
@@ -24,7 +23,6 @@ ext.expansions = { oss ->
     'jdkUrl' : 'https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz',
     'jdkVersion' : '11.0.1',
     'license': oss ? 'Apache-2.0' : 'Elastic License',
-    'ingest-geoip' : "ingest-geoip-${VersionProperties.elasticsearch}.zip",
     'ingest-user-agent' : "ingest-user-agent-${VersionProperties.elasticsearch}.zip",
     'version' : VersionProperties.elasticsearch
   ]
diff --git a/distribution/docker/src/docker/Dockerfile b/distribution/docker/src/docker/Dockerfile
index cdc8591dc30..e42f66d8386 100644
--- a/distribution/docker/src/docker/Dockerfile
+++ b/distribution/docker/src/docker/Dockerfile
@@ -30,9 +30,8 @@ RUN groupadd -g 1000 elasticsearch && \
 
 WORKDIR /usr/share/elasticsearch
 
-COPY ${elasticsearch} ${ingest-geoip} ${ingest-user-agent} /opt/
+COPY ${elasticsearch} ${ingest-user-agent} /opt/
 RUN tar zxf /opt/${elasticsearch} --strip-components=1
-RUN elasticsearch-plugin install --batch file:///opt/${ingest-geoip}
 RUN elasticsearch-plugin install --batch file:///opt/${ingest-user-agent}
 RUN mkdir -p config data logs
 RUN chmod 0775 config data logs
diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
index fc2da33c3a6..290107ad93a 100644
--- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
+++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
@@ -222,6 +222,10 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
             throw new UserException(ExitCodes.USAGE, "plugin id is required");
         }
 
+        if ("ingest-geoip".equals(pluginId)) {
+            handleInstallIngestGeoIp();
+        }
+
         if ("x-pack".equals(pluginId)) {
             handleInstallXPack(buildFlavor());
         }
@@ -231,6 +235,12 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
         install(terminal, isBatch, extractedZip, env);
     }
 
+    private static void handleInstallIngestGeoIp() throws UserException {
+        throw new UserException(
+                ExitCodes.OK,
+                "ingest-geoip is no longer a plugin but instead a module packaged with this distribution of Elasticsearch");
+    }
+
     Build.Flavor buildFlavor() {
         return Build.CURRENT.flavor();
     }
diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
index 16f5fdb4740..20526df133c 100644
--- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
+++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
@@ -111,6 +111,14 @@ class RemovePluginCommand extends EnvironmentAwareCommand {
          */
         if ((!Files.exists(pluginDir) && !Files.exists(pluginConfigDir) && !Files.exists(removing))
                 || (!Files.exists(pluginDir) && Files.exists(pluginConfigDir) && !purge)) {
+
+            // special case for ingest-geoip since it is a module now but could have been installed from a previous when it was a plugin
+            if ("ingest-geoip".equals(pluginName)) {
+                throw new UserException(
+                        ExitCodes.OK,
+                        "ingest-geoip is no longer a plugin but instead a module packaged with this distribution of Elasticsearch");
+            }
+
             final String message = String.format(
                     Locale.ROOT, "plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins", pluginName);
             throw new UserException(ExitCodes.CONFIG, message);
diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
index 248eb364ebc..c6ae8f9c7e3 100644
--- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
+++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
@@ -757,6 +757,17 @@ public class InstallPluginCommandTests extends ESTestCase {
         }
     }
 
+    public void testInstallGeoIp() throws IOException {
+        final Environment environment = createEnv(fs, temp).v2();
+        final UserException exception =
+                expectThrows(UserException.class, () -> new InstallPluginCommand().execute(terminal, "ingest-geoip", false, environment));
+        assertThat(exception.exitCode, equalTo(ExitCodes.OK));
+        assertThat(
+                exception,
+                hasToString(containsString(
+                        "ingest-geoip is no longer a plugin but instead a module packaged with this distribution of Elasticsearch")));
+    }
+
     public void testInstallXPack() throws IOException {
         runInstallXPackTest(Build.Flavor.DEFAULT, UserException.class, "this distribution of Elasticsearch contains X-Pack by default");
         runInstallXPackTest(
diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
index c62d37a4e28..639898748e2 100644
--- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
+++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
@@ -29,6 +29,7 @@ import org.elasticsearch.env.Environment;
 import org.elasticsearch.env.TestEnvironment;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.VersionUtils;
+import org.hamcrest.Matchers;
 import org.junit.Before;
 
 import java.io.BufferedReader;
@@ -251,6 +252,33 @@ public class RemovePluginCommandTests extends ESTestCase {
         assertEquals("plugin name is required", e.getMessage());
     }
 
+    /**
+     * The ingest-geoip plugin receives special handling because we have re-packaged it as a module; this test ensures that we are still
+     * able to uninstall an old installation of ingest-geoip.
+     *
+     * @throws Exception if an exception is thrown creating or removing the plugin
+     */
+    public void testRemoveIngestGeoIp() throws Exception {
+        createPlugin(
+                "ingest-geoip",
+                VersionUtils.randomVersionBetween(
+                        random(),
+                        Version.CURRENT.minimumIndexCompatibilityVersion(),
+                        Version.V_6_6_0));
+        removePlugin("ingest-geoip", home, randomBoolean());
+        assertThat(Files.exists(env.pluginsFile().resolve("ingest-geoip")), equalTo(false));
+        assertRemoveCleaned(env);
+    }
+
+    public void testRemoveIngestGeoIpWhenNotInstalled() {
+        final UserException e = expectThrows(UserException.class, () -> removePlugin("ingest-geoip", home, randomBoolean()));
+        assertThat(e.exitCode, equalTo(ExitCodes.OK));
+        assertThat(
+                e,
+                hasToString(Matchers.containsString(
+                        "ingest-geoip is no longer a plugin but instead a module packaged with this distribution of Elasticsearch")));
+    }
+
     public void testRemoveWhenRemovingMarker() throws Exception {
         createPlugin("fake");
         Files.createFile(env.pluginsFile().resolve("fake").resolve("plugin.jar"));
diff --git a/docs/plugins/ingest.asciidoc b/docs/plugins/ingest.asciidoc
index fa316c3862f..3c8a4b1f8d7 100644
--- a/docs/plugins/ingest.asciidoc
+++ b/docs/plugins/ingest.asciidoc
@@ -13,14 +13,6 @@ The core ingest plugins are:
 The ingest attachment plugin lets Elasticsearch extract file attachments in common formats (such as PPT, XLS, and PDF) by
 using the Apache text extraction library http://lucene.apache.org/tika/[Tika].
 
-<<ingest-geoip>>::
-
-The GeoIP processor adds information about the geographical location of IP addresses, based on data from the Maxmind databases.
-This processor adds this information by default under the `geoip` field.
-+
-The ingest-geoip plugin ships by default with the GeoLite2 City and GeoLite2 Country geoip2 databases from Maxmind made available
-under the CCA-ShareAlike 3.0 license. For more details see, http://dev.maxmind.com/geoip/geoip2/geolite2/.
-
 <<ingest-user-agent>>::
 
 A processor that extracts details from the User-Agent header value.
@@ -34,6 +26,4 @@ The following plugin has been contributed by our community:
 
 include::ingest-attachment.asciidoc[]
 
-include::ingest-geoip.asciidoc[]
-
 include::ingest-user-agent.asciidoc[]
\ No newline at end of file
diff --git a/docs/reference/cat/plugins.asciidoc b/docs/reference/cat/plugins.asciidoc
index 4f3bd8f3b54..529d711a32a 100644
--- a/docs/reference/cat/plugins.asciidoc
+++ b/docs/reference/cat/plugins.asciidoc
@@ -25,7 +25,6 @@ U7321H6 discovery-azure-classic {version_qualified} The Azure Classic Discovery
 U7321H6 discovery-ec2           {version_qualified} The EC2 discovery plugin allows to use AWS API for the unicast discovery mechanism.
 U7321H6 discovery-gce           {version_qualified} The Google Compute Engine (GCE) Discovery plugin allows to use GCE API for the unicast discovery mechanism.
 U7321H6 ingest-attachment       {version_qualified} Ingest processor that uses Apache Tika to extract contents
-U7321H6 ingest-geoip            {version_qualified} Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database
 U7321H6 ingest-user-agent       {version_qualified} Ingest processor that extracts information from a user agent
 U7321H6 mapper-annotated-text   {version_qualified} The Mapper Annotated_text plugin adds support for text fields with markup used to inject annotation tokens into the index.
 U7321H6 mapper-murmur3          {version_qualified} The Mapper Murmur3 plugin allows to compute hashes of a field's values at index-time and to store them in the index.
diff --git a/docs/reference/cluster/nodes-info.asciidoc b/docs/reference/cluster/nodes-info.asciidoc
index 2cd61dd905f..4844a9a8bb0 100644
--- a/docs/reference/cluster/nodes-info.asciidoc
+++ b/docs/reference/cluster/nodes-info.asciidoc
@@ -159,13 +159,6 @@ The result will look similar to:
           "classname": "org.elasticsearch.plugin.analysis.icu.AnalysisICUPlugin",
           "has_native_controller": false
         },
-        {
-          "name": "ingest-geoip",
-          "version": "{version}",
-          "description": "Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database",
-          "classname": "org.elasticsearch.ingest.geoip.IngestGeoIpPlugin",
-          "has_native_controller": false
-        },
         {
           "name": "ingest-user-agent",
           "version": "{version}",
diff --git a/docs/reference/cluster/stats.asciidoc b/docs/reference/cluster/stats.asciidoc
index a6295395422..eae87fb5025 100644
--- a/docs/reference/cluster/stats.asciidoc
+++ b/docs/reference/cluster/stats.asciidoc
@@ -186,13 +186,6 @@ Will return, for example:
           "classname": "org.elasticsearch.plugin.analysis.icu.AnalysisICUPlugin",
           "has_native_controller": false
         },
-        {
-          "name": "ingest-geoip",
-          "version": "{version}",
-          "description": "Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database",
-          "classname": "org.elasticsearch.ingest.geoip.IngestGeoIpPlugin",
-          "has_native_controller": false
-        },
         {
           "name": "ingest-user-agent",
           "version": "{version}",
diff --git a/docs/reference/ingest/ingest-node.asciidoc b/docs/reference/ingest/ingest-node.asciidoc
index 89adbbb9b7c..5bc90003e02 100644
--- a/docs/reference/ingest/ingest-node.asciidoc
+++ b/docs/reference/ingest/ingest-node.asciidoc
@@ -1310,10 +1310,10 @@ doesn't exist on all nodes. If you rely on custom processor plugins make sure to
 
 [source,yaml]
 --------------------------------------------------
-plugin.mandatory: ingest-attachment,ingest-geoip
+plugin.mandatory: ingest-attachment
 --------------------------------------------------
 
-A node will not start if either of these plugins are not available.
+A node will not start if this plugin is not available.
 
 The <<ingest-stats,node stats API>> can be used to fetch ingest usage statistics, globally and on a per
 pipeline basis. Useful to find out which pipelines are used the most or spent the most time on preprocessing.
@@ -1334,6 +1334,7 @@ include::processors/dot-expand.asciidoc[]
 include::processors/drop.asciidoc[]
 include::processors/fail.asciidoc[]
 include::processors/foreach.asciidoc[]
+include::processors/geoip.asciidoc[]
 include::processors/grok.asciidoc[]
 include::processors/gsub.asciidoc[]
 include::processors/join.asciidoc[]
diff --git a/docs/plugins/ingest-geoip.asciidoc b/docs/reference/ingest/processors/geoip.asciidoc
similarity index 96%
rename from docs/plugins/ingest-geoip.asciidoc
rename to docs/reference/ingest/processors/geoip.asciidoc
index f4795f6620a..6385871c2a2 100644
--- a/docs/plugins/ingest-geoip.asciidoc
+++ b/docs/reference/ingest/processors/geoip.asciidoc
@@ -1,20 +1,17 @@
 [[ingest-geoip]]
-=== Ingest Geoip Processor Plugin
+=== Ingest Geoip Processor
 
 The GeoIP processor adds information about the geographical location of IP addresses, based on data from the Maxmind databases.
 This processor adds this information by default under the `geoip` field. The `geoip` processor can resolve both IPv4 and
 IPv6 addresses.
 
-The ingest-geoip plugin ships by default with the GeoLite2 City, GeoLite2 Country and GeoLite2 ASN geoip2 databases from Maxmind made available
+The ingest-geoip module ships by default with the GeoLite2 City, GeoLite2 Country and GeoLite2 ASN geoip2 databases from Maxmind made available
 under the CCA-ShareAlike 4.0 license. For more details see, http://dev.maxmind.com/geoip/geoip2/geolite2/
 
 The GeoIP processor can run with other geoip2 databases from Maxmind. The files must be copied into the geoip config directory,
 and the `database_file` option should be used to specify the filename of the custom database. Custom database files must be stored
 uncompressed. The geoip config directory is located at `$ES_HOME/config/ingest-geoip` and holds the shipped databases too.
 
-:plugin_name: ingest-geoip
-include::install_remove.asciidoc[]
-
 [[using-ingest-geoip]]
 ==== Using the Geoip Processor in a Pipeline
 
@@ -25,7 +22,7 @@ include::install_remove.asciidoc[]
 | Name                   | Required  | Default                                                                            | Description
 | `field`                | yes       | -                                                                                  | The field to get the ip address from for the geographical lookup.
 | `target_field`         | no        | geoip                                                                              | The field that will hold the geographical information looked up from the Maxmind database.
-| `database_file`        | no        | GeoLite2-City.mmdb                                                                 | The database filename in the geoip config directory. The ingest-geoip plugin ships with the GeoLite2-City.mmdb, GeoLite2-Country.mmdb and GeoLite2-ASN.mmdb files.
+| `database_file`        | no        | GeoLite2-City.mmdb                                                                 | The database filename in the geoip config directory. The ingest-geoip module ships with the GeoLite2-City.mmdb, GeoLite2-Country.mmdb and GeoLite2-ASN.mmdb files.
 | `properties`           | no        | [`continent_name`, `country_iso_code`, `region_iso_code`, `region_name`, `city_name`, `location`] *   | Controls what properties are added to the `target_field` based on the geoip lookup.
 | `ignore_missing`       | no        | `false`                                                                            | If `true` and `field` does not exist, the processor quietly exits without modifying the document
 |======
@@ -91,7 +88,7 @@ Which returns:
 
 Here is an example that uses the default country database and adds the
 geographical information to the `geo` field based on the `ip` field`. Note that
-this database is included in the plugin download. So this:
+this database is included in the module. So this:
 
 [source,js]
 --------------------------------------------------
@@ -190,7 +187,7 @@ Which returns:
 
 [[ingest-geoip-mappings-note]]
 ===== Recognizing Location as a Geopoint
-Although this plugin enriches your document with a `location` field containing
+Although this processor enriches your document with a `location` field containing
 the estimated latitude and longitude of the IP address, this field will not be
 indexed as a {ref}/geo-point.html[`geo_point`] type in Elasticsearch without explicitely defining it
 as such in the mapping.
diff --git a/plugins/ingest-geoip/build.gradle b/modules/ingest-geoip/build.gradle
similarity index 100%
rename from plugins/ingest-geoip/build.gradle
rename to modules/ingest-geoip/build.gradle
diff --git a/plugins/ingest-geoip/licenses/geoip2-2.9.0.jar.sha1 b/modules/ingest-geoip/licenses/geoip2-2.9.0.jar.sha1
similarity index 100%
rename from plugins/ingest-geoip/licenses/geoip2-2.9.0.jar.sha1
rename to modules/ingest-geoip/licenses/geoip2-2.9.0.jar.sha1
diff --git a/plugins/ingest-geoip/licenses/geoip2-LICENSE.txt b/modules/ingest-geoip/licenses/geoip2-LICENSE.txt
similarity index 100%
rename from plugins/ingest-geoip/licenses/geoip2-LICENSE.txt
rename to modules/ingest-geoip/licenses/geoip2-LICENSE.txt
diff --git a/plugins/ingest-geoip/licenses/geoip2-NOTICE.txt b/modules/ingest-geoip/licenses/geoip2-NOTICE.txt
similarity index 100%
rename from plugins/ingest-geoip/licenses/geoip2-NOTICE.txt
rename to modules/ingest-geoip/licenses/geoip2-NOTICE.txt
diff --git a/plugins/ingest-geoip/licenses/jackson-annotations-2.8.11.jar.sha1 b/modules/ingest-geoip/licenses/jackson-annotations-2.8.11.jar.sha1
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-annotations-2.8.11.jar.sha1
rename to modules/ingest-geoip/licenses/jackson-annotations-2.8.11.jar.sha1
diff --git a/plugins/ingest-geoip/licenses/jackson-annotations-LICENSE b/modules/ingest-geoip/licenses/jackson-annotations-LICENSE
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-annotations-LICENSE
rename to modules/ingest-geoip/licenses/jackson-annotations-LICENSE
diff --git a/plugins/ingest-geoip/licenses/jackson-annotations-NOTICE b/modules/ingest-geoip/licenses/jackson-annotations-NOTICE
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-annotations-NOTICE
rename to modules/ingest-geoip/licenses/jackson-annotations-NOTICE
diff --git a/plugins/ingest-geoip/licenses/jackson-databind-2.8.11.jar.sha1 b/modules/ingest-geoip/licenses/jackson-databind-2.8.11.jar.sha1
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-databind-2.8.11.jar.sha1
rename to modules/ingest-geoip/licenses/jackson-databind-2.8.11.jar.sha1
diff --git a/plugins/ingest-geoip/licenses/jackson-databind-LICENSE b/modules/ingest-geoip/licenses/jackson-databind-LICENSE
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-databind-LICENSE
rename to modules/ingest-geoip/licenses/jackson-databind-LICENSE
diff --git a/plugins/ingest-geoip/licenses/jackson-databind-NOTICE b/modules/ingest-geoip/licenses/jackson-databind-NOTICE
similarity index 100%
rename from plugins/ingest-geoip/licenses/jackson-databind-NOTICE
rename to modules/ingest-geoip/licenses/jackson-databind-NOTICE
diff --git a/plugins/ingest-geoip/licenses/maxmind-db-1.2.2.jar.sha1 b/modules/ingest-geoip/licenses/maxmind-db-1.2.2.jar.sha1
similarity index 100%
rename from plugins/ingest-geoip/licenses/maxmind-db-1.2.2.jar.sha1
rename to modules/ingest-geoip/licenses/maxmind-db-1.2.2.jar.sha1
diff --git a/plugins/ingest-geoip/licenses/maxmind-db-LICENSE.txt b/modules/ingest-geoip/licenses/maxmind-db-LICENSE.txt
similarity index 100%
rename from plugins/ingest-geoip/licenses/maxmind-db-LICENSE.txt
rename to modules/ingest-geoip/licenses/maxmind-db-LICENSE.txt
diff --git a/plugins/ingest-geoip/licenses/maxmind-db-NOTICE.txt b/modules/ingest-geoip/licenses/maxmind-db-NOTICE.txt
similarity index 100%
rename from plugins/ingest-geoip/licenses/maxmind-db-NOTICE.txt
rename to modules/ingest-geoip/licenses/maxmind-db-NOTICE.txt
diff --git a/plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java
similarity index 100%
rename from plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java
rename to modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java
diff --git a/plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpProcessor.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpProcessor.java
similarity index 100%
rename from plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpProcessor.java
rename to modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpProcessor.java
diff --git a/plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
similarity index 99%
rename from plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
rename to modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
index aad7051b8d1..8769a643e1d 100644
--- a/plugins/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
+++ b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java
@@ -90,7 +90,7 @@ public class IngestGeoIpPlugin extends Plugin implements IngestPlugin, Closeable
     private Path getGeoIpDirectory(Processor.Parameters parameters) {
         final Path geoIpDirectory;
         if (parameters.env.settings().get("ingest.geoip.database_path") == null) {
-            geoIpDirectory = parameters.env.pluginsFile().resolve("ingest-geoip");
+            geoIpDirectory = parameters.env.modulesFile().resolve("ingest-geoip");
         } else {
             geoIpDirectory = PathUtils.get(parameters.env.settings().get("ingest.geoip.database_path"));
         }
diff --git a/plugins/ingest-geoip/src/main/plugin-metadata/plugin-security.policy b/modules/ingest-geoip/src/main/plugin-metadata/plugin-security.policy
similarity index 100%
rename from plugins/ingest-geoip/src/main/plugin-metadata/plugin-security.policy
rename to modules/ingest-geoip/src/main/plugin-metadata/plugin-security.policy
diff --git a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorFactoryTests.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorFactoryTests.java
similarity index 100%
rename from plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorFactoryTests.java
rename to modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorFactoryTests.java
diff --git a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorNonIngestNodeTests.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorNonIngestNodeTests.java
similarity index 100%
rename from plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorNonIngestNodeTests.java
rename to modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorNonIngestNodeTests.java
diff --git a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorTests.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorTests.java
similarity index 100%
rename from plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorTests.java
rename to modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/GeoIpProcessorTests.java
diff --git a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java
similarity index 99%
rename from plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java
rename to modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java
index 9d9bdb9c7d0..c247011d5d0 100644
--- a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java
+++ b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpClientYamlTestSuiteIT.java
@@ -36,4 +36,3 @@ public class IngestGeoIpClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase
         return ESClientYamlSuiteTestCase.createParameters();
     }
 }
-
diff --git a/plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpPluginTests.java b/modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpPluginTests.java
similarity index 100%
rename from plugins/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpPluginTests.java
rename to modules/ingest-geoip/src/test/java/org/elasticsearch/ingest/geoip/IngestGeoIpPluginTests.java
diff --git a/plugins/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml b/modules/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml
similarity index 74%
rename from plugins/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml
rename to modules/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml
index ef6346d4256..5cd45da2bda 100644
--- a/plugins/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml
+++ b/modules/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/10_basic.yml
@@ -1,4 +1,4 @@
-"Ingest plugin installed":
+"ingest-geoip installed":
     - skip:
         reason: "contains is a newly added assertion"
         features: contains
@@ -10,5 +10,5 @@
     - do:
         nodes.info: {}
 
-    - contains:  { nodes.$master.plugins: { name: ingest-geoip } }
+    - contains:  { nodes.$master.modules: { name: ingest-geoip } }
     - contains:  { nodes.$master.ingest.processors: { type: geoip } }
diff --git a/plugins/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/20_geoip_processor.yml b/modules/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/20_geoip_processor.yml
similarity index 100%
rename from plugins/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/20_geoip_processor.yml
rename to modules/ingest-geoip/src/test/resources/rest-api-spec/test/ingest_geoip/20_geoip_processor.yml
diff --git a/qa/smoke-test-ingest-with-all-dependencies/build.gradle b/qa/smoke-test-ingest-with-all-dependencies/build.gradle
index 1d318f6be66..b2295f535ba 100644
--- a/qa/smoke-test-ingest-with-all-dependencies/build.gradle
+++ b/qa/smoke-test-ingest-with-all-dependencies/build.gradle
@@ -22,12 +22,8 @@ apply plugin: 'elasticsearch.rest-test'
 
 dependencies {
     testCompile project(path: ':modules:ingest-common', configuration: 'runtime')
-    testCompile project(path: ':plugins:ingest-geoip', configuration: 'runtime')
+    testCompile project(path: ':modules:ingest-geoip', configuration: 'runtime')
     testCompile project(path: ':modules:lang-mustache', configuration: 'runtime')
     testCompile project(path: ':modules:lang-painless', configuration: 'runtime')
     testCompile project(path: ':modules:reindex', configuration: 'runtime')
 }
-
-integTestCluster {
-    plugin ':plugins:ingest-geoip'
-}
diff --git a/qa/vagrant/src/test/resources/packaging/tests/module_and_plugin_test_cases.bash b/qa/vagrant/src/test/resources/packaging/tests/module_and_plugin_test_cases.bash
index d4ef82c4a18..c3b77e3efac 100644
--- a/qa/vagrant/src/test/resources/packaging/tests/module_and_plugin_test_cases.bash
+++ b/qa/vagrant/src/test/resources/packaging/tests/module_and_plugin_test_cases.bash
@@ -231,10 +231,6 @@ fi
     install_and_check_plugin ingest attachment bcprov-jdk15on-*.jar tika-core-*.jar pdfbox-*.jar poi-4.0.0.jar poi-ooxml-4.0.0.jar poi-ooxml-schemas-*.jar poi-scratchpad-*.jar
 }
 
-@test "[$GROUP] install ingest-geoip plugin" {
-    install_and_check_plugin ingest geoip geoip2-*.jar jackson-annotations-*.jar jackson-databind-*.jar maxmind-db-*.jar
-}
-
 @test "[$GROUP] install ingest-user-agent plugin" {
     install_and_check_plugin ingest user-agent
 }
@@ -243,6 +239,10 @@ fi
     check_module ingest-common jcodings-*.jar joni-*.jar
 }
 
+@test "[$GROUP] check ingest-geoip module" {
+    check_module ingest-geoip geoip2-*.jar jackson-annotations-*.jar jackson-databind-*.jar maxmind-db-*.jar
+}
+
 @test "[$GROUP] check lang-expression module" {
     # we specify the version on the asm-5.0.4.jar so that the test does
     # not spuriously pass if the jar is missing but the other asm jars
@@ -364,10 +364,6 @@ fi
     remove_plugin ingest-attachment
 }
 
-@test "[$GROUP] remove ingest-geoip plugin" {
-    remove_plugin ingest-geoip
-}
-
 @test "[$GROUP] remove ingest-user-agent plugin" {
     remove_plugin ingest-user-agent
 }