Serve keys from canonical project name

Rather than asking users to know the 'source' name in order to
retrieve the project's public key, use the tenant and canonical
project name.  The tenant already appears in most web urls, and
the project name should be known to the user.

Change-Id: Icd1269ffdd8879bd177fd452978a2c88b2f1b205
diff --git a/doc/source/user/encryption.rst b/doc/source/user/encryption.rst
index 7ced589..d45195f 100644
--- a/doc/source/user/encryption.rst
+++ b/doc/source/user/encryption.rst
@@ -15,9 +15,8 @@
 which can be used by anyone to encrypt a secret and only Zuul is able
 to decrypt it.  Zuul serves each project's public key using its
 build-in webserver.  They can be fetched at the path
-``/keys/<source>/<project>.pub`` where ``<project>`` is the name of a
-project and ``<source>`` is the name of that project's connection in
-the main Zuul configuration file.
+``/<tenant>/<project>.pub`` where ``<project>`` is the canonical name
+of a project and ``<tenant>`` is the name of a tenant with that project.
 
 Zuul currently supports one encryption scheme, PKCS#1 with OAEP, which
 can not store secrets longer than the 3760 bits (derived from the key
diff --git a/tools/encrypt_secret.py b/tools/encrypt_secret.py
index 9b52846..2a4ea1d 100755
--- a/tools/encrypt_secret.py
+++ b/tools/encrypt_secret.py
@@ -43,10 +43,7 @@
     parser.add_argument('url',
                         help="The base URL of the zuul server and tenant.  "
                         "E.g., https://zuul.example.com/tenant-name")
-    # TODO(jeblair,mordred): When projects have canonical names, use that here.
     # TODO(jeblair): Throw a fit if SSL is not used.
-    parser.add_argument('source',
-                        help="The Zuul source of the project.")
     parser.add_argument('project',
                         help="The name of the project.")
     parser.add_argument('--infile',
@@ -61,8 +58,7 @@
                         "to standard output.")
     args = parser.parse_args()
 
-    req = Request("%s/keys/%s/%s.pub" % (
-        args.url, args.source, args.project))
+    req = Request("%s/%s.pub" % (args.url, args.project))
     pubkey = urlopen(req)
 
     if args.infile:
diff --git a/zuul/rpclistener.py b/zuul/rpclistener.py
index d40505e..e5016df 100644
--- a/zuul/rpclistener.py
+++ b/zuul/rpclistener.py
@@ -303,8 +303,7 @@
 
     def handle_key_get(self, job):
         args = json.loads(job.arguments)
-        source_name, project_name = args.get("source"), args.get("project")
-        source = self.sched.connections.getSource(source_name)
-        project = source.getProject(project_name)
+        tenant = self.sched.abide.tenants.get(args.get("tenant"))
+        (trusted, project) = tenant.getProject(args.get("project"))
         job.sendWorkComplete(
             encryption.serialize_rsa_public_key(project.public_key))
diff --git a/zuul/web/__init__.py b/zuul/web/__init__.py
index e4a3612..795103d 100755
--- a/zuul/web/__init__.py
+++ b/zuul/web/__init__.py
@@ -193,9 +193,9 @@
         return web.json_response(json.loads(job.data[0]))
 
     def key_get(self, request):
-        source = request.match_info["source"]
+        tenant = request.match_info["tenant"]
         project = request.match_info["project"]
-        job = self.rpc.submitJob('zuul:key_get', {'source': source,
+        job = self.rpc.submitJob('zuul:key_get', {'tenant': tenant,
                                                   'project': project})
         return web.Response(body=job.data[0])
 
@@ -375,7 +375,7 @@
             ('GET', '/{tenant}/status.json', self._handleStatusRequest),
             ('GET', '/{tenant}/jobs.json', self._handleJobsRequest),
             ('GET', '/{tenant}/console-stream', self._handleWebsocket),
-            ('GET', '/{source}/{project}.pub', self._handleKeyRequest),
+            ('GET', '/{tenant}/{project}.pub', self._handleKeyRequest),
             ('GET', '/{tenant}/status.html', self._handleStaticRequest),
             ('GET', '/{tenant}/jobs.html', self._handleStaticRequest),
             ('GET', '/{tenant}/stream.html', self._handleStaticRequest),