Repository: certbot/certbot

Issue:
Ensure rename doesn't break third party plugins
There are a lot of third party plugins for Let's Encrypt (listed here: https://letsencrypt.readthedocs.org/en/latest/using.html#plugins)
It's possible that they reference things in such a way that changing the name or package of LE will break their compatibility with the client - we should ensure that they are unbroken



Discussion:
This might require some of the clients to make new releases that fix any breakage caused


Resolving patch:
diff --git a/certbot/constants.py b/certbot/constants.py
--- a/certbot/constants.py
+++ b/certbot/constants.py
@@ -8,6 +8,9 @@
 SETUPTOOLS_PLUGINS_ENTRY_POINT = "certbot.plugins"
 """Setuptools entry point group name for plugins."""
 
+OLD_SETUPTOOLS_PLUGINS_ENTRY_POINT = "letsencrypt.plugins"
+"""Plugins Setuptools entry point before rename."""
+
 CLI_DEFAULTS = dict(
     config_files=[
         "/etc/letsencrypt/cli.ini",
diff --git a/certbot/plugins/disco.py b/certbot/plugins/disco.py
--- a/certbot/plugins/disco.py
+++ b/certbot/plugins/disco.py
@@ -1,5 +1,6 @@
 """Utilities for plugins discovery and selection."""
 import collections
+import itertools
 import logging
 import pkg_resources
 
@@ -164,8 +165,12 @@ def __init__(self, plugins):
     def find_all(cls):
         """Find plugins using setuptools entry points."""
         plugins = {}
-        for entry_point in pkg_resources.iter_entry_points(
-                constants.SETUPTOOLS_PLUGINS_ENTRY_POINT):
+        entry_points = itertools.chain(
+            pkg_resources.iter_entry_points(
+                constants.SETUPTOOLS_PLUGINS_ENTRY_POINT),
+            pkg_resources.iter_entry_points(
+                constants.OLD_SETUPTOOLS_PLUGINS_ENTRY_POINT),)
+        for entry_point in entry_points:
             plugin_ep = PluginEntryPoint(entry_point)
             assert plugin_ep.name not in plugins, (
                 "PREFIX_FREE_DISTRIBUTIONS messed up")


Test patch:
diff --git a/certbot/plugins/disco_test.py b/certbot/plugins/disco_test.py
--- a/certbot/plugins/disco_test.py
+++ b/certbot/plugins/disco_test.py
@@ -9,11 +9,16 @@
 from certbot import interfaces
 
 from certbot.plugins import standalone
+from certbot.plugins import webroot
 
 EP_SA = pkg_resources.EntryPoint(
     "sa", "certbot.plugins.standalone",
     attrs=("Authenticator",),
     dist=mock.MagicMock(key="certbot"))
+EP_WR = pkg_resources.EntryPoint(
+    "wr", "certbot.plugins.webroot",
+    attrs=("Authenticator",),
+    dist=mock.MagicMock(key="certbot"))
 
 
 class PluginEntryPointTest(unittest.TestCase):
@@ -176,10 +181,13 @@ def setUp(self):
     def test_find_all(self):
         from certbot.plugins.disco import PluginsRegistry
         with mock.patch("certbot.plugins.disco.pkg_resources") as mock_pkg:
-            mock_pkg.iter_entry_points.return_value = iter([EP_SA])
+            mock_pkg.iter_entry_points.side_effect = [iter([EP_SA]),
+                                                      iter([EP_WR])]
             plugins = PluginsRegistry.find_all()
         self.assertTrue(plugins["sa"].plugin_cls is standalone.Authenticator)
         self.assertTrue(plugins["sa"].entry_point is EP_SA)
+        self.assertTrue(plugins["wr"].plugin_cls is webroot.Authenticator)
+        self.assertTrue(plugins["wr"].entry_point is EP_WR)
 
     def test_getitem(self):
         self.assertEqual(self.plugin_ep, self.reg["mock"])