Merge "Simplify the log url" into feature/zuulv3
diff --git a/tests/fixtures/config/success-url/git/common-config/zuul.yaml b/tests/fixtures/config/success-url/git/common-config/zuul.yaml
index f2d5251..b3ecf6d 100644
--- a/tests/fixtures/config/success-url/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/success-url/git/common-config/zuul.yaml
@@ -19,7 +19,7 @@
 
 - job:
     name: docs-draft-test
-    success-url: http://docs-draft.example.org/{build.parameters[LOG_PATH]}/publish-docs/
+    success-url: http://docs-draft.example.org/{change.number:.2}/{change.number}/{change.patchset}/{pipeline.name}/{job.name}/{build.uuid:.7}/publish-docs/
 
 - job:
     name: docs-draft-test2
diff --git a/zuul/executor/client.py b/zuul/executor/client.py
index 20bc3ef..90cfa9b 100644
--- a/zuul/executor/client.py
+++ b/zuul/executor/client.py
@@ -16,7 +16,6 @@
 import gear
 import json
 import logging
-import os
 import time
 import threading
 from uuid import uuid4
@@ -266,13 +265,6 @@
             params['ZUUL_REF'] = item.change.ref
             params['ZUUL_COMMIT'] = item.change.newrev
 
-        # The destination_path is a unique path for this build request
-        # and generally where the logs are expected to be placed
-        destination_path = os.path.join(item.change.getBasePath(),
-                                        pipeline.name, job.name, uuid[:7])
-        params['BASE_LOG_PATH'] = item.change.getBasePath()
-        params['LOG_PATH'] = destination_path
-
         # This is what we should be heading toward for parameters:
 
         # required:
diff --git a/zuul/model.py b/zuul/model.py
index d347071..a4ac278 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -96,6 +96,13 @@
     return re.sub(' ', '-', name)
 
 
+class Attributes(object):
+    """A class to hold attributes for string formatting."""
+
+    def __init__(self, **kw):
+        setattr(self, '__dict__', kw)
+
+
 class Pipeline(object):
     """A configuration that ties triggers, reporters, managers and sources.
 
@@ -1502,12 +1509,20 @@
             if job.failure_url:
                 pattern = job.failure_url
         url = None
+        # Produce safe versions of objects which may be useful in
+        # result formatting, but don't allow users to crawl through
+        # the entire data structure where they might be able to access
+        # secrets, etc.
+        safe_change = self.change.getSafeAttributes()
+        safe_pipeline = Attributes(name=self.pipeline.name)
+        safe_job = Attributes(name=job.name)
+        safe_build = Attributes(uuid=build.uuid)
         if pattern:
             try:
-                url = pattern.format(change=self.change,
-                                     pipeline=self.pipeline,
-                                     job=job,
-                                     build=build)
+                url = pattern.format(change=safe_change,
+                                     pipeline=safe_pipeline,
+                                     job=safe_job,
+                                     build=safe_build)
             except Exception:
                 pass  # FIXME: log this or something?
         if not url:
@@ -1700,6 +1715,12 @@
     def updatesConfig(self):
         return False
 
+    def getSafeAttributes(self):
+        return Attributes(project=self.project,
+                          ref=self.ref,
+                          oldrev=self.oldrev,
+                          newrev=self.newrev)
+
 
 class Change(Ref):
     """A proposed new state for a Project."""
@@ -1763,6 +1784,11 @@
             return True
         return False
 
+    def getSafeAttributes(self):
+        return Attributes(project=self.project,
+                          number=self.number,
+                          patchset=self.patchset)
+
 
 class TriggerEvent(object):
     """Incoming event from an external system."""
diff --git a/zuul/scheduler.py b/zuul/scheduler.py
index 6ae8492..952ad9a 100644
--- a/zuul/scheduler.py
+++ b/zuul/scheduler.py
@@ -915,6 +915,7 @@
             url_pattern = self.config.get('zuul', 'url_pattern')
         else:
             url_pattern = None
+        # TODOv3(jhesketh): url_pattern should be deterministic by zuul
 
         data = {}