Description: Add heat_api_root configuration variable
Author: Thomas Goirand <zigo@debian.org>
Forwarded: https://review.opendev.org/c/openstack/heat/+/813036
Last-Update: 2021-10-07

Index: heat/heat/api/openstack/v1/util.py
===================================================================
--- heat.orig/heat/api/openstack/v1/util.py
+++ heat/heat/api/openstack/v1/util.py
@@ -15,9 +15,13 @@ import functools
 
 from webob import exc
 
+from oslo_config import cfg
+
 from heat.common.i18n import _
 from heat.common import identifier
 
+CONF = cfg.CONF
+
 
 def registered_policy_enforce(handler):
     """Decorator that enforces policies.
@@ -96,7 +100,15 @@ def make_url(req, identity):
         err_reason = _('Invalid Stack address')
         raise exc.HTTPInternalServerError(err_reason)
 
-    return req.relative_url(stack_identity.url_path(), True)
+    url_stack_identity = stack_identity.url_path()
+
+    heat_api_root = CONF.heat_api.heat_api_root
+    if heat_api_root is None:
+        url = req.relative_url(url_stack_identity, True)
+    else:
+        url = heat_api_root + '/' + url_stack_identity
+
+    return url
 
 
 def make_link(req, identity, relationship='self'):
Index: heat/heat/common/wsgi.py
===================================================================
--- heat.orig/heat/common/wsgi.py
+++ heat/heat/common/wsgi.py
@@ -40,6 +40,23 @@
 LOG = logging.getLogger(__name__)
 URL_LENGTH_LIMIT = 50000
 
+api_opts = [
+    cfg.StrOpt('heat_api_root',
+               default=None,
+               sample_default='https://example.com/orchestration/v1',
+               help=_('Root of the Heat API URL. Set this if the Heat API URL '
+                      'is not set to the root of your web server. This '
+                      'influences the way href links are written inside '
+                      'stacks when doing a stack show. Leave this value '
+                      'commented or set to None if Heat API is served at the '
+                      'root of your server.')),
+]
+
+api_group = cfg.OptGroup('heat_api')
+cfg.CONF.register_group(api_group)
+cfg.CONF.register_opts(api_opts,
+                       group=api_group)
+
 json_size_opt = cfg.IntOpt('max_json_body_size',
                            default=1048576,
                            help=_('Maximum raw byte size of JSON request body.'
@@ -49,6 +66,7 @@
 
 def list_opts():
     yield None, [json_size_opt]
+    yield 'heat_api', api_opts
 
 
 class Middleware(object):
