Generate the endpoint map statically
authorZane Bitter <zbitter@redhat.com>
Tue, 2 Feb 2016 17:32:37 +0000 (12:32 -0500)
committerZane Bitter <zbitter@redhat.com>
Wed, 24 Feb 2016 16:18:46 +0000 (11:18 -0500)
A stack is an extremely heavyweight abstraction in Heat. Particularly in
TripleO, every stack includes a copy of all the template and environment
data for all of the stacks in the tree, all of which must be stored anew
in the database.

The EndpointMap abstraction created no fewer than 30 nested stacks, none
of which contained any resources but which existed purely for the
purpose of abstracting out some intrinsic functions used to calculate
the endpoint URLs for the various services. This likely adds several GB
to the memory requirements of the undercloud, and can cause things to
slow to a crawl since all 30 nested stacks need to be queried whenever
we need data from any one of them.

This change eliminates the nested stacks and instead generates the
endpoint map statically. This can be done offline in less than 250ms,
allows the input data to be expressed in an even more human-readable
form, and reduces the runtime overhead of the endpoints map by a factor
of 31, all with no loss of functionality, compatibility or flexibility.

Since we don't run a setup script to generate the tarball, the
endpoint_map.yaml output is checked in to source control. The build
script offers a --check option that can be used to make sure that the
output file is up-to-date with the input data.

Change-Id: I2df8f5569d81c1bde417ff5b12b06b7f1e19c336

network/endpoints/build_endpoint_map.py [new file with mode: 0755]
network/endpoints/endpoint.yaml [deleted file]
network/endpoints/endpoint_data.yaml [new file with mode: 0644]
network/endpoints/endpoint_map.yaml
overcloud-resource-registry-puppet.yaml

diff --git a/network/endpoints/build_endpoint_map.py b/network/endpoints/build_endpoint_map.py
new file mode 100755 (executable)
index 0000000..056d688
--- /dev/null
@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+
+"""
+Generate the endpoint_map.yaml template from data in the endpoint_data.yaml
+file.
+
+By default the files in the same directory as this script are operated on, but
+different files can be optionally specified on the command line.
+
+The --check option verifies that the current output file is up-to-date with the
+latest data in the input file. The script exits with status code 2 if a
+mismatch is detected.
+"""
+
+from __future__ import print_function
+
+
+__all__ = ['load_endpoint_data', 'generate_endpoint_map_template',
+           'write_template', 'build_endpoint_map', 'check_up_to_date']
+
+
+import collections
+import copy
+import itertools
+import os
+import sys
+import yaml
+
+
+(IN_FILE, OUT_FILE) = ('endpoint_data.yaml', 'endpoint_map.yaml')
+
+SUBST = (SUBST_IP_ADDRESS, SUBST_CLOUDNAME) = ('IP_ADDRESS', 'CLOUDNAME')
+PARAMS = (PARAM_CLOUDNAME, PARAM_ENDPOINTMAP) = ('CloudName', 'EndpointMap')
+FIELDS = (F_PORT, F_PROTOCOL, F_HOST) = ('port', 'protocol', 'host')
+
+ENDPOINT_TYPES = frozenset(['Internal', 'Public', 'Admin'])
+
+
+def get_file(default_fn, override=None, writable=False):
+    if override == '-':
+        if writable:
+            return sys.stdout
+        else:
+            return sys.stdin
+
+    if override is not None:
+        filename = override
+    else:
+        filename = os.path.join(os.path.dirname(__file__), default_fn)
+
+    return open(filename, 'w' if writable else 'r')
+
+
+def load_endpoint_data(infile=None):
+    with get_file(IN_FILE, infile) as f:
+        return yaml.safe_load(f)
+
+
+def vip_param_name(endpoint_type_defn):
+    return endpoint_type_defn['vip_param'] + 'VirtualIP'
+
+
+def vip_param_names(config):
+    def ep_types(svc):
+        return (v for k, v in svc.items() if k in ENDPOINT_TYPES or not k)
+
+    return set(vip_param_name(defn)
+               for svc in config.values() for defn in ep_types(svc))
+
+
+def endpoint_map_default(config):
+    def map_item(ep_name, ep_type, svc):
+        values = collections.OrderedDict([
+            (F_PROTOCOL, svc.get(F_PROTOCOL, 'http')),
+            (F_PORT, str(svc[ep_type].get(F_PORT, svc[F_PORT]))),
+            (F_HOST, SUBST_IP_ADDRESS),
+        ])
+        return ep_name + ep_type, values
+
+    return collections.OrderedDict(map_item(ep_name, ep_type, svc)
+                                   for ep_name, svc in sorted(config.items())
+                                   for ep_type in sorted(set(svc) &
+                                                         ENDPOINT_TYPES))
+
+
+def make_parameter(ptype, default, description=None):
+    param = collections.OrderedDict([('type', ptype), ('default', default)])
+    if description is not None:
+        param['description'] = description
+    return param
+
+
+def template_parameters(config):
+    params = collections.OrderedDict((n, make_parameter('string', ''))
+                                     for n in sorted(vip_param_names(config)))
+
+    params[PARAM_ENDPOINTMAP] = make_parameter('json',
+                                               endpoint_map_default(config),
+                                               'Mapping of service endpoint '
+                                               '-> protocol. Typically set '
+                                               'via parameter_defaults in the '
+                                               'resource registry.')
+
+    params[PARAM_CLOUDNAME] = make_parameter('string',
+                                             'overcloud',
+                                             'The DNS name of this cloud. '
+                                             'e.g. ci-overcloud.tripleo.org')
+    return params
+
+
+def template_output_definition(endpoint_name,
+                               endpoint_variant,
+                               endpoint_type,
+                               vip_param,
+                               uri_suffix=None,
+                               name_override=None):
+    def extract_field(field):
+        assert field in FIELDS
+        return {'get_param': ['EndpointMap',
+                              endpoint_name + endpoint_type,
+                              copy.copy(field)]}
+
+    port = extract_field(F_PORT)
+    protocol = extract_field(F_PROTOCOL)
+    host = {
+        'str_replace': collections.OrderedDict([
+            ('template', extract_field(F_HOST)),
+            ('params', {
+                SUBST_IP_ADDRESS: {'get_param': vip_param},
+                SUBST_CLOUDNAME: {'get_param': PARAM_CLOUDNAME},
+            })
+        ])
+    }
+    uri_fields = [protocol, '://', copy.deepcopy(host), ':', port]
+    uri_fields_suffix = (copy.deepcopy(uri_fields) +
+                         ([uri_suffix] if uri_suffix is not None else []))
+
+    name = name_override if name_override is not None else (endpoint_name +
+                                                            endpoint_variant +
+                                                            endpoint_type)
+
+    return name, {
+        'host': host,
+        'port': extract_field('port'),
+        'protocol': extract_field('protocol'),
+        'uri': {
+            'list_join': ['', uri_fields_suffix]
+        },
+        'uri_no_suffix': {
+            'list_join': ['', uri_fields]
+        },
+    }
+
+
+def template_endpoint_items(config):
+    def get_svc_endpoints(ep_name, svc):
+        for ep_type in set(svc) & ENDPOINT_TYPES:
+            defn = svc[ep_type]
+            for variant, suffix in defn.get('uri_suffixes',
+                                            {'': None}).items():
+                name_override = defn.get('names', {}).get(variant)
+                yield template_output_definition(ep_name, variant, ep_type,
+                                                 vip_param_name(defn),
+                                                 suffix,
+                                                 name_override)
+
+    return itertools.chain.from_iterable(sorted(get_svc_endpoints(ep_name,
+                                                                  svc))
+                                         for (ep_name,
+                                              svc) in sorted(config.items()))
+
+
+def generate_endpoint_map_template(config):
+    return collections.OrderedDict([
+        ('heat_template_version', '2015-04-30'),
+        ('description', 'A map of OpenStack endpoints.'),
+        ('parameters', template_parameters(config)),
+        ('outputs', {
+            'endpoint_map': {
+                'value':
+                    collections.OrderedDict(template_endpoint_items(config))
+            }
+        }),
+    ])
+
+
+autogen_warning = """### DO NOT MODIFY THIS FILE
+### This file is automatically generated from endpoint_data.yaml
+### by the script build_endpoint_map.py
+
+"""
+
+
+class TemplateDumper(yaml.SafeDumper):
+    def represent_ordered_dict(self, data):
+        return self.represent_dict(data.items())
+
+
+TemplateDumper.add_representer(collections.OrderedDict,
+                               TemplateDumper.represent_ordered_dict)
+
+
+def write_template(template, filename=None):
+    with get_file(OUT_FILE, filename, writable=True) as f:
+        f.write(autogen_warning)
+        yaml.dump(template, f, TemplateDumper, width=68)
+
+
+def read_template(template, filename=None):
+    with get_file(OUT_FILE, filename) as f:
+        return yaml.safe_load(f)
+
+
+def build_endpoint_map(output_filename=None, input_filename=None):
+    if output_filename is not None and output_filename == input_filename:
+        raise Exception('Cannot read from and write to the same file')
+    config = load_endpoint_data(input_filename)
+    template = generate_endpoint_map_template(config)
+    write_template(template, output_filename)
+
+
+def check_up_to_date(output_filename=None, input_filename=None):
+    if output_filename is not None and output_filename == input_filename:
+        raise Exception('Input and output filenames must be different')
+    config = load_endpoint_data(input_filename)
+    template = generate_endpoint_map_template(config)
+    existing_template = read_template(output_filename)
+    return existing_template == template
+
+
+def get_options():
+    from optparse import OptionParser
+
+    parser = OptionParser('usage: %prog'
+                          ' [-i INPUT_FILE] [-o OUTPUT_FILE] [--check]',
+                          description=__doc__)
+    parser.add_option('-i', '--input', dest='input_file', action='store',
+                      default=None,
+                      help='Specify a different endpoint data file')
+    parser.add_option('-o', '--output', dest='output_file', action='store',
+                      default=None,
+                      help='Specify a different endpoint map template file')
+    parser.add_option('-c', '--check', dest='check', action='store_true',
+                      default=False, help='Check that the output file is '
+                                          'up to date with the data')
+    parser.add_option('-d', '--debug', dest='debug', action='store_true',
+                      default=False, help='Print stack traces on error')
+
+    return parser.parse_args()
+
+
+def main():
+    options, args = get_options()
+    if args:
+        print('Warning: ignoring positional args: %s' % ' '.join(args),
+              file=sys.stderr)
+
+    try:
+        if options.check:
+            if not check_up_to_date(options.output_file, options.input_file):
+                print('EndpointMap template does not match input data',
+                      file=sys.stderr)
+                sys.exit(2)
+        else:
+            build_endpoint_map(options.output_file, options.input_file)
+    except Exception as exc:
+        if options.debug:
+            raise
+        print('%s: %s' % (type(exc).__name__, str(exc)), file=sys.stderr)
+        sys.exit(1)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/network/endpoints/endpoint.yaml b/network/endpoints/endpoint.yaml
deleted file mode 100644 (file)
index 6246cfd..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-heat_template_version: 2015-04-30
-
-description: >
-  OpenStack Endpoint
-
-parameters:
-  EndpointName:
-    type: string
-    description: The name of the Endpoint being evaluated
-  EndpointMap:
-    type: json
-    default: {}
-    description: Mapping of service endpoint -> protocol. Typically set
-                 via parameter_defaults in the resource registry.
-  IP:
-    type: string
-    description: The IP address of the Neutron Port that the endpoint is attached to
-  UriSuffix:
-    type: string
-    default: ''
-    description: A suffix attached to the URL
-  CloudName:
-    type: string
-    default: ''
-    description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
-
-outputs:
-  endpoint:
-    description: >
-      A Hash containing a mapping of service endpoints to ports, protocols, uris
-      assigned IPs, and hostnames for a specific endpoint
-    value:
-      port: {get_param: [EndpointMap, {get_param: EndpointName }, port] }
-      protocol: {get_param: [EndpointMap, {get_param: EndpointName }, protocol] }
-      ip: {get_param: IP}
-      host:
-        str_replace:
-          template: {get_param: [EndpointMap, {get_param: EndpointName }, host]}
-          params: {IP_ADDRESS: {get_param: IP}, CLOUDNAME: {get_param: CloudName}}
-      uri:
-        list_join:
-          - ''
-          - - {get_param: [EndpointMap, {get_param: EndpointName }, protocol] }
-            - '://'
-            - str_replace:
-                template: {get_param: [EndpointMap, {get_param: EndpointName }, host]}
-                params: {IP_ADDRESS: {get_param: IP}, CLOUDNAME: {get_param: CloudName }}
-            - ':'
-            - {get_param: [EndpointMap, {get_param: EndpointName }, port] }
-            - {get_param: UriSuffix }
-      uri_no_suffix:
-        list_join:
-          - ''
-          - - {get_param: [EndpointMap, {get_param: EndpointName }, protocol] }
-            - '://'
-            - str_replace:
-                template: {get_param: [EndpointMap, {get_param: EndpointName }, host]}
-                params: {IP_ADDRESS: {get_param: IP}, CLOUDNAME: {get_param: CloudName} }
-            - ':'
-            - {get_param: [EndpointMap, {get_param: EndpointName }, port] }
diff --git a/network/endpoints/endpoint_data.yaml b/network/endpoints/endpoint_data.yaml
new file mode 100644 (file)
index 0000000..ac1e042
--- /dev/null
@@ -0,0 +1,185 @@
+# Data in this file is used to generate the endpoint_map.yaml template.
+# Run the script build_endpoint_map.py to regenerate the file.
+
+Ceilometer:
+    Internal:
+        vip_param: CeilometerApi
+    Public:
+        vip_param: Public
+    Admin:
+        vip_param: CeilometerApi
+    port: 8777
+
+Cinder:
+    Internal:
+        vip_param: CinderApi
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+            V2: /v2/%(tenant_id)s
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+            V2: /v2/%(tenant_id)s
+    Admin:
+        vip_param: CinderApi
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+            V2: /v2/%(tenant_id)s
+    port: 8776
+
+Glance:
+    Internal:
+        vip_param: GlanceApi
+    Public:
+        vip_param: Public
+    Admin:
+        vip_param: GlanceApi
+    port: 9292
+
+GlanceRegistry:
+    Internal:
+        vip_param: GlanceRegistry
+    Public:
+        vip_param: Public
+    Admin:
+        vip_param: GlanceRegistry
+    port: 9191
+
+Mysql:
+    '':
+        vip_param: Mysql
+
+Heat:
+    Internal:
+        vip_param: HeatApi
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+    Admin:
+        vip_param: HeatApi
+        uri_suffixes:
+            '': /v1/%(tenant_id)s
+    port: 8004
+
+Horizon:
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /dashboard
+    port: 80
+
+Keystone:
+    Internal:
+        vip_param: KeystonePublicApi
+        uri_suffixes:
+            '': /v2.0
+            EC2: /v2.0/ec2tokens
+        names:
+            EC2: KeystoneEC2
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v2.0
+    Admin:
+        vip_param: KeystoneAdminApi
+        uri_suffixes:
+            '': /v2.0
+        port: 35357
+    port: 5000
+
+# TODO(ayoung): V3 is a temporary fix. Endpoints should be versionless.
+# Required for https://bugs.launchpad.net/puppet-nova/+bug/1542486
+KeystoneV3:
+    Internal:
+        vip_param: KeystonePublicApi
+        uri_suffixes:
+            '': /v3
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v3
+    Admin:
+        vip_param: KeystoneAdminApi
+        uri_suffixes:
+            '': /v3
+        port: 35357
+    port: 5000
+
+Neutron:
+    Internal:
+        vip_param: NeutronApi
+    Public:
+        vip_param: Public
+    Admin:
+        vip_param: NeutronApi
+    port: 9696
+
+Nova:
+    Internal:
+        vip_param: NovaApi
+        uri_suffixes:
+            '': /v2/%(tenant_id)s
+            V3: /v3
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v2/%(tenant_id)s
+            V3: /v3
+    Admin:
+        vip_param: NovaApi
+        uri_suffixes:
+            '': /v2/%(tenant_id)s
+            V3: /v3
+    port: 8774
+
+NovaEC2:
+    Internal:
+        vip_param: NovaApi
+        uri_suffixes:
+            '': /services/Cloud
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /services/Cloud
+    Admin:
+        vip_param: NovaApi
+        uri_suffixes:
+            '': /services/Admin
+    port: 8773
+
+Swift:
+    Internal:
+        vip_param: SwiftProxy
+        uri_suffixes:
+            '': /v1/AUTH_%(tenant_id)s
+            S3:
+    Public:
+        vip_param: Public
+        uri_suffixes:
+            '': /v1/AUTH_%(tenant_id)s
+            S3:
+    Admin:
+        vip_param: SwiftProxy
+        uri_suffixes:
+            '':
+            S3:
+    port: 8080
+
+Sahara:
+    Internal:
+        vip_param: SaharaApi
+        uri_suffixes:
+            '': /v1.1/%(tenant_id)s
+    Public:
+        vip_param: SaharaApi
+        uri_suffixes:
+            '': /v1.1/%(tenant_id)s
+    Admin:
+        vip_param: SaharaApi
+        uri_suffixes:
+            '': /v1.1/%(tenant_id)s
+    port: 8386
index dff5f97..46765cc 100644 (file)
-heat_template_version: 2015-04-30
-
-description: >
-  A Map of OpenStack Endpoints
+### DO NOT MODIFY THIS FILE
+### This file is automatically generated from endpoint_data.yaml
+### by the script build_endpoint_map.py
 
+heat_template_version: '2015-04-30'
+description: A map of OpenStack endpoints.
 parameters:
-  CeilometerApiVirtualIP:
-    type: string
-    default: ''
-  CinderApiVirtualIP:
-    type: string
-    default: ''
-  GlanceApiVirtualIP:
-    type: string
-    default: ''
-  GlanceRegistryVirtualIP:
-    type: string
-    default: ''
-  HeatApiVirtualIP:
-    type: string
-    default: ''
-  KeystoneAdminApiVirtualIP:
-    type: string
-    default: ''
-  KeystonePublicApiVirtualIP:
-    type: string
-    default: ''
-  MysqlVirtualIP:
-    type: string
-    default: ''
-  NeutronApiVirtualIP:
-    type: string
-    default: ''
-  NovaApiVirtualIP:
-    type: string
-    default: ''
-  PublicVirtualIP:
-    type: string
-    default: ''
-  SwiftProxyVirtualIP:
-    type: string
-    default: ''
-  SaharaApiVirtualIP:
-    type: string
-    default: ''
+  CeilometerApiVirtualIP: {type: string, default: ''}
+  CinderApiVirtualIP: {type: string, default: ''}
+  GlanceApiVirtualIP: {type: string, default: ''}
+  GlanceRegistryVirtualIP: {type: string, default: ''}
+  HeatApiVirtualIP: {type: string, default: ''}
+  KeystoneAdminApiVirtualIP: {type: string, default: ''}
+  KeystonePublicApiVirtualIP: {type: string, default: ''}
+  MysqlVirtualIP: {type: string, default: ''}
+  NeutronApiVirtualIP: {type: string, default: ''}
+  NovaApiVirtualIP: {type: string, default: ''}
+  PublicVirtualIP: {type: string, default: ''}
+  SaharaApiVirtualIP: {type: string, default: ''}
+  SwiftProxyVirtualIP: {type: string, default: ''}
   EndpointMap:
     type: json
     default:
-      CeilometerAdmin: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
-      CeilometerInternal: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
-      CeilometerPublic: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
-      CinderAdmin: {protocol: 'http', port: '8776', host: 'IP_ADDRESS'}
-      CinderInternal: {protocol: 'http', port: '8776', host: 'IP_ADDRESS'}
-      CinderPublic: {protocol: 'http', port: '8776', host: 'IP_ADDRESS'}
-      GlanceAdmin: {protocol: 'http', port: '9292', host: 'IP_ADDRESS'}
-      GlanceInternal: {protocol: 'http', port: '9292', host: 'IP_ADDRESS'}
-      GlancePublic: {protocol: 'http', port: '9292', host: 'IP_ADDRESS'}
-      GlanceRegistryAdmin: {protocol: 'http', port: '9191', host: 'IP_ADDRESS'}
-      GlanceRegistryInternal: {protocol: 'http', port: '9191', host: 'IP_ADDRESS'}
-      GlanceRegistryPublic: {protocol: 'http', port: '9191', host: 'IP_ADDRESS'}
-      HeatAdmin: {protocol: 'http', port: '8004', host: 'IP_ADDRESS'}
-      HeatInternal: {protocol: 'http', port: '8004', host: 'IP_ADDRESS'}
-      HeatPublic: {protocol: 'http', port: '8004', host: 'IP_ADDRESS'}
-      HorizonPublic: {protocol: 'http', port: '80', host: 'IP_ADDRESS'}
-      KeystoneAdmin: {protocol: 'http', port: '35357', host: 'IP_ADDRESS'}
-      KeystoneInternal: {protocol: 'http', port: '5000', host: 'IP_ADDRESS'}
-      KeystonePublic: {protocol: 'http', port: '5000', host: 'IP_ADDRESS'}
-      KeystoneV3Admin: {protocol: 'http', port: '35357', host: 'IP_ADDRESS'}
-      KeystoneV3Internal: {protocol: 'http', port: '5000', host: 'IP_ADDRESS'}
-      KeystoneV3Public: {protocol: 'http', port: '5000', host: 'IP_ADDRESS'}
-      NeutronAdmin: {protocol: 'http', port: '9696', host: 'IP_ADDRESS'}
-      NeutronInternal: {protocol: 'http', port: '9696', host: 'IP_ADDRESS'}
-      NeutronPublic: {protocol: 'http', port: '9696', host: 'IP_ADDRESS'}
-      NovaAdmin: {protocol: 'http', port: '8774', host: 'IP_ADDRESS'}
-      NovaInternal: {protocol: 'http', port: '8774', host: 'IP_ADDRESS'}
-      NovaPublic: {protocol: 'http', port: '8774', host: 'IP_ADDRESS'}
-      NovaEC2Admin: {protocol: 'http', port: '8773', host: 'IP_ADDRESS'}
-      NovaEC2Internal: {protocol: 'http', port: '8773', host: 'IP_ADDRESS'}
-      NovaEC2Public: {protocol: 'http', port: '8773', host: 'IP_ADDRESS'}
-      NovaVNCProxyAdmin: {protocol: 'http', port: '6080', host: 'IP_ADDRESS'}
-      NovaVNCProxyInternal: {protocol: 'http', port: '6080', host: 'IP_ADDRESS'}
-      NovaVNCProxyPublic: {protocol: 'http', port: '6080', host: 'IP_ADDRESS'}
-      SwiftAdmin: {protocol: 'http', port: '8080', host: 'IP_ADDRESS'}
-      SwiftInternal: {protocol: 'http', port: '8080', host: 'IP_ADDRESS'}
-      SwiftPublic: {protocol: 'http', port: '8080', host: 'IP_ADDRESS'}
-      SaharaAdmin: {protocol: 'http', port: '8386', host: 'IP_ADDRESS'}
-      SaharaInternal: {protocol: 'http', port: '8386', host: 'IP_ADDRESS'}
-      SaharaPublic: {protocol: 'http', port: '8386', host: 'IP_ADDRESS'}
+      CeilometerAdmin: {protocol: http, port: '8777', host: IP_ADDRESS}
+      CeilometerInternal: {protocol: http, port: '8777', host: IP_ADDRESS}
+      CeilometerPublic: {protocol: http, port: '8777', host: IP_ADDRESS}
+      CinderAdmin: {protocol: http, port: '8776', host: IP_ADDRESS}
+      CinderInternal: {protocol: http, port: '8776', host: IP_ADDRESS}
+      CinderPublic: {protocol: http, port: '8776', host: IP_ADDRESS}
+      GlanceAdmin: {protocol: http, port: '9292', host: IP_ADDRESS}
+      GlanceInternal: {protocol: http, port: '9292', host: IP_ADDRESS}
+      GlancePublic: {protocol: http, port: '9292', host: IP_ADDRESS}
+      GlanceRegistryAdmin: {protocol: http, port: '9191', host: IP_ADDRESS}
+      GlanceRegistryInternal: {protocol: http, port: '9191', host: IP_ADDRESS}
+      GlanceRegistryPublic: {protocol: http, port: '9191', host: IP_ADDRESS}
+      HeatAdmin: {protocol: http, port: '8004', host: IP_ADDRESS}
+      HeatInternal: {protocol: http, port: '8004', host: IP_ADDRESS}
+      HeatPublic: {protocol: http, port: '8004', host: IP_ADDRESS}
+      HorizonPublic: {protocol: http, port: '80', host: IP_ADDRESS}
+      KeystoneAdmin: {protocol: http, port: '35357', host: IP_ADDRESS}
+      KeystoneInternal: {protocol: http, port: '5000', host: IP_ADDRESS}
+      KeystonePublic: {protocol: http, port: '5000', host: IP_ADDRESS}
+      KeystoneV3Admin: {protocol: http, port: '35357', host: IP_ADDRESS}
+      KeystoneV3Internal: {protocol: http, port: '5000', host: IP_ADDRESS}
+      KeystoneV3Public: {protocol: http, port: '5000', host: IP_ADDRESS}
+      NeutronAdmin: {protocol: http, port: '9696', host: IP_ADDRESS}
+      NeutronInternal: {protocol: http, port: '9696', host: IP_ADDRESS}
+      NeutronPublic: {protocol: http, port: '9696', host: IP_ADDRESS}
+      NovaAdmin: {protocol: http, port: '8774', host: IP_ADDRESS}
+      NovaInternal: {protocol: http, port: '8774', host: IP_ADDRESS}
+      NovaPublic: {protocol: http, port: '8774', host: IP_ADDRESS}
+      NovaEC2Admin: {protocol: http, port: '8773', host: IP_ADDRESS}
+      NovaEC2Internal: {protocol: http, port: '8773', host: IP_ADDRESS}
+      NovaEC2Public: {protocol: http, port: '8773', host: IP_ADDRESS}
+      SaharaAdmin: {protocol: http, port: '8386', host: IP_ADDRESS}
+      SaharaInternal: {protocol: http, port: '8386', host: IP_ADDRESS}
+      SaharaPublic: {protocol: http, port: '8386', host: IP_ADDRESS}
+      SwiftAdmin: {protocol: http, port: '8080', host: IP_ADDRESS}
+      SwiftInternal: {protocol: http, port: '8080', host: IP_ADDRESS}
+      SwiftPublic: {protocol: http, port: '8080', host: IP_ADDRESS}
     description: Mapping of service endpoint -> protocol. Typically set
-                 via parameter_defaults in the resource registry.
-  CloudName:
-    type: string
-    default: overcloud
-    description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
-
-resources:
-
-  CeilometerInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CeilometerInternal
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CeilometerApiVirtualIP}
-  CeilometerPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CeilometerPublic
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: PublicVirtualIP}
-  CeilometerAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CeilometerAdmin
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CeilometerApiVirtualIP}
-
-  CinderInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderInternal
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CinderApiVirtualIP}
-      UriSuffix: '/v1/%(tenant_id)s'
-  CinderPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderPublic
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: PublicVirtualIP}
-      UriSuffix: '/v1/%(tenant_id)s'
-  CinderAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderAdmin
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CinderApiVirtualIP}
-      UriSuffix: '/v1/%(tenant_id)s'
-
-  CinderV2Internal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderInternal
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CinderApiVirtualIP}
-      UriSuffix: '/v2/%(tenant_id)s'
-  CinderV2Public:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderPublic
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: PublicVirtualIP}
-      UriSuffix: '/v2/%(tenant_id)s'
-  CinderV2Admin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: CinderAdmin
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: CinderApiVirtualIP}
-      UriSuffix: '/v2/%(tenant_id)s'
-
-  GlanceInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlanceInternal
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: GlanceApiVirtualIP}
-  GlancePublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlancePublic
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: PublicVirtualIP}
-  GlanceAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlanceAdmin
-      EndpointMap: { get_param: EndpointMap }
-      CloudName: {get_param: CloudName}
-      IP: {get_param: GlanceApiVirtualIP}
-  GlanceRegistryInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlanceRegistryInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: GlanceRegistryVirtualIP}
-  GlanceRegistryPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlanceRegistryPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-  GlanceRegistryAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: GlanceRegistryAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: GlanceRegistryVirtualIP}
-
-  HeatInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: HeatInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: HeatApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1/%(tenant_id)s'
-  HeatPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: HeatPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1/%(tenant_id)s'
-  HeatAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: HeatAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: HeatApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1/%(tenant_id)s'
-
-  HorizonPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: HorizonPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/dashboard'
-
-  KeystoneInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: KeystonePublicApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2.0'
-  KeystonePublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystonePublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2.0'
-  KeystoneAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: KeystoneAdminApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2.0'
-  KeystoneEC2:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: KeystonePublicApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2.0/ec2tokens'
-  # TODO(ayoung): V3 is a temporary fix. Endpoints should be versionless.
-  # Required for https://bugs.launchpad.net/puppet-nova/+bug/1542486
-  KeystoneV3Internal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneV3Internal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: KeystonePublicApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-  KeystoneV3Public:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneV3Public
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-  KeystoneV3Admin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: KeystoneV3Admin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: KeystoneAdminApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-
-  NeutronInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NeutronInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NeutronApiVirtualIP}
-      CloudName: {get_param: CloudName}
-  NeutronPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NeutronPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-  NeutronAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NeutronAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NeutronApiVirtualIP}
-      CloudName: {get_param: CloudName}
-
-  NovaInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2/%(tenant_id)s'
-  NovaPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2/%(tenant_id)s'
-  NovaAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v2/%(tenant_id)s'
-  NovaV3Internal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-  NovaV3Public:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-  NovaV3Admin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v3'
-
-  NovaEC2Internal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaEC2Internal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/services/Cloud'
-  NovaEC2Public:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaEC2Public
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/services/Cloud'
-  NovaEC2Admin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaEC2Admin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/services/Admin'
-
-  NovaVNCProxyInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaVNCProxyInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-  NovaVNCProxyPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaVNCProxyPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-  NovaVNCProxyAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: NovaVNCProxyAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: NovaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-
-  SwiftInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SwiftProxyVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1/AUTH_%(tenant_id)s'
-  SwiftPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1/AUTH_%(tenant_id)s'
-  SwiftAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SwiftProxyVirtualIP}
-      CloudName: {get_param: CloudName}
-      # No Suffix for the Admin interface
-  SwiftS3Internal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SwiftProxyVirtualIP}
-      CloudName: {get_param: CloudName}
-  SwiftS3Public:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: PublicVirtualIP}
-      CloudName: {get_param: CloudName}
-  SwiftS3Admin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SwiftAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SwiftProxyVirtualIP}
-      CloudName: {get_param: CloudName}
-
-  SaharaInternal:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SaharaInternal
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SaharaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1.1/%(tenant_id)s'
-  SaharaPublic:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SaharaPublic
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SaharaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1.1/%(tenant_id)s'
-  SaharaAdmin:
-    type: OS::TripleO::Endpoint
-    properties:
-      EndpointName: SaharaAdmin
-      EndpointMap: { get_param: EndpointMap }
-      IP: {get_param: SaharaApiVirtualIP}
-      CloudName: {get_param: CloudName}
-      UriSuffix: '/v1.1/%(tenant_id)s'
-
+      via parameter_defaults in the resource registry.
+  CloudName: {type: string, default: overcloud, description: The DNS name
+      of this cloud. e.g. ci-overcloud.tripleo.org}
 outputs:
   endpoint_map:
     value:
-      CeilometerInternal: {get_attr: [ CeilometerInternal, endpoint] }
-      CeilometerPublic: {get_attr: [ CeilometerPublic, endpoint] }
-      CeilometerAdmin: {get_attr: [ CeilometerAdmin, endpoint] }
-      CinderInternal: {get_attr: [ CinderInternal, endpoint] }
-      CinderPublic: {get_attr: [ CinderPublic, endpoint] }
-      CinderAdmin: {get_attr: [ CinderAdmin, endpoint] }
-      CinderV2Internal: {get_attr: [ CinderV2Internal, endpoint] }
-      CinderV2Public: {get_attr: [ CinderV2Public, endpoint] }
-      CinderV2Admin: {get_attr: [ CinderV2Admin, endpoint] }
-      GlanceInternal: {get_attr: [ GlanceInternal, endpoint] }
-      GlancePublic: {get_attr: [ GlancePublic, endpoint] }
-      GlanceAdmin: {get_attr: [ GlanceAdmin, endpoint] }
-      GlanceRegistryInternal: {get_attr: [ GlanceRegistryInternal, endpoint] }
-      GlanceRegistryPublic: {get_attr: [ GlanceRegistryPublic, endpoint] }
-      GlanceRegistryAdmin: {get_attr: [ GlanceRegistryAdmin, endpoint] }
-      HeatInternal: {get_attr: [ HeatInternal, endpoint] }
-      HeatPublic: {get_attr: [ HeatPublic, endpoint] }
-      HeatAdmin: {get_attr: [ HeatAdmin, endpoint] }
-      HorizonPublic: {get_attr: [ HorizonPublic, endpoint] }
-      KeystoneInternal: {get_attr: [ KeystoneInternal, endpoint] }
-      KeystonePublic: {get_attr: [ KeystonePublic, endpoint] }
-      KeystoneAdmin: {get_attr: [ KeystoneAdmin, endpoint] }
-      KeystoneEC2: {get_attr: [ KeystoneEC2, endpoint] }
-      KeystoneV3Internal: {get_attr: [ KeystoneV3Internal, endpoint] }
-      KeystoneV3Public: {get_attr: [ KeystoneV3Public, endpoint] }
-      KeystoneV3Admin: {get_attr: [ KeystoneV3Admin, endpoint] }
-      NeutronInternal: {get_attr: [ NeutronInternal, endpoint] }
-      NeutronPublic: {get_attr: [ NeutronPublic, endpoint] }
-      NeutronAdmin: {get_attr: [ NeutronAdmin, endpoint] }
-      NovaInternal: {get_attr: [ NovaInternal, endpoint] }
-      NovaPublic: {get_attr: [ NovaPublic, endpoint] }
-      NovaAdmin: {get_attr: [ NovaAdmin, endpoint] }
-      NovaV3Internal: {get_attr: [ NovaV3Internal, endpoint] }
-      NovaV3Public: {get_attr: [ NovaV3Public, endpoint] }
-      NovaV3Admin: {get_attr: [ NovaV3Admin, endpoint] }
-      NovaEC2Internal: {get_attr: [ NovaEC2Internal, endpoint] }
-      NovaEC2Public: {get_attr: [ NovaEC2Public, endpoint] }
-      NovaEC2Admin: {get_attr: [ NovaEC2Admin, endpoint] }
-      NovaVNCProxyInternal: {get_attr: [ NovaVNCProxyInternal, endpoint] }
-      NovaVNCProxyPublic: {get_attr: [ NovaVNCProxyPublic, endpoint] }
-      NovaVNCProxyAdmin: {get_attr: [ NovaVNCProxyAdmin, endpoint] }
-      SwiftInternal: {get_attr: [ SwiftInternal, endpoint] }
-      SwiftPublic: {get_attr: [ SwiftPublic, endpoint] }
-      SwiftAdmin: {get_attr: [ SwiftAdmin, endpoint] }
-      SwiftS3Internal: {get_attr: [ SwiftS3Internal, endpoint] }
-      SwiftS3Public: {get_attr: [ SwiftS3Public, endpoint] }
-      SwiftS3Admin: {get_attr: [ SwiftS3Admin, endpoint] }
-      SaharaInternal: {get_attr: [ SaharaInternal, endpoint] }
-      SaharaPublic: {get_attr: [ SaharaPublic, endpoint] }
-      SaharaAdmin: {get_attr: [ SaharaAdmin, endpoint] }
+      CeilometerAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CeilometerAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CeilometerAdmin, port]
+        protocol:
+          get_param: [EndpointMap, CeilometerAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerAdmin, port]
+      CeilometerInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CeilometerInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CeilometerInternal, port]
+        protocol:
+          get_param: [EndpointMap, CeilometerInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerInternal, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CeilometerApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerInternal, port]
+      CeilometerPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CeilometerPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, CeilometerPublic, port]
+        protocol:
+          get_param: [EndpointMap, CeilometerPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerPublic, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CeilometerPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CeilometerPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CeilometerPublic, port]
+      CinderAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CinderApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderAdmin, port]
+        protocol:
+          get_param: [EndpointMap, CinderAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderAdmin, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderAdmin, port]
+      CinderInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CinderApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderInternal, port]
+        protocol:
+          get_param: [EndpointMap, CinderInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderInternal, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderInternal, port]
+      CinderPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderPublic, port]
+        protocol:
+          get_param: [EndpointMap, CinderPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderPublic, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderPublic, port]
+      CinderV2Admin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CinderApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderAdmin, port]
+        protocol:
+          get_param: [EndpointMap, CinderAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderAdmin, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderAdmin, port]
+      CinderV2Internal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: CinderApiVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderInternal, port]
+        protocol:
+          get_param: [EndpointMap, CinderInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderInternal, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: CinderApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderInternal, port]
+      CinderV2Public:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, CinderPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, CinderPublic, port]
+        protocol:
+          get_param: [EndpointMap, CinderPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderPublic, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, CinderPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, CinderPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, CinderPublic, port]
+      GlanceAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlanceAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+        port:
+          get_param: [EndpointMap, GlanceAdmin, port]
+        protocol:
+          get_param: [EndpointMap, GlanceAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceAdmin, port]
+      GlanceInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlanceInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+        port:
+          get_param: [EndpointMap, GlanceInternal, port]
+        protocol:
+          get_param: [EndpointMap, GlanceInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceInternal, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceInternal, port]
+      GlancePublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlancePublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, GlancePublic, port]
+        protocol:
+          get_param: [EndpointMap, GlancePublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlancePublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlancePublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlancePublic, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlancePublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlancePublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlancePublic, port]
+      GlanceRegistryAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlanceRegistryAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+        port:
+          get_param: [EndpointMap, GlanceRegistryAdmin, port]
+        protocol:
+          get_param: [EndpointMap, GlanceRegistryAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryAdmin, port]
+      GlanceRegistryInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlanceRegistryInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+        port:
+          get_param: [EndpointMap, GlanceRegistryInternal, port]
+        protocol:
+          get_param: [EndpointMap, GlanceRegistryInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryInternal, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: GlanceRegistryVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryInternal, port]
+      GlanceRegistryPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, GlanceRegistryPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, GlanceRegistryPublic, port]
+        protocol:
+          get_param: [EndpointMap, GlanceRegistryPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryPublic, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, GlanceRegistryPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, GlanceRegistryPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, GlanceRegistryPublic, port]
+      HeatAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, HeatAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: HeatApiVirtualIP}
+        port:
+          get_param: [EndpointMap, HeatAdmin, port]
+        protocol:
+          get_param: [EndpointMap, HeatAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: HeatApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatAdmin, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: HeatApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatAdmin, port]
+      HeatInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, HeatInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: HeatApiVirtualIP}
+        port:
+          get_param: [EndpointMap, HeatInternal, port]
+        protocol:
+          get_param: [EndpointMap, HeatInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: HeatApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatInternal, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: HeatApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatInternal, port]
+      HeatPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, HeatPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, HeatPublic, port]
+        protocol:
+          get_param: [EndpointMap, HeatPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatPublic, port]
+            - /v1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HeatPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HeatPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HeatPublic, port]
+      HorizonPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, HorizonPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, HorizonPublic, port]
+        protocol:
+          get_param: [EndpointMap, HorizonPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HorizonPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HorizonPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HorizonPublic, port]
+            - /dashboard
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, HorizonPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, HorizonPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, HorizonPublic, port]
+      KeystoneAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneAdmin, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneAdmin, port]
+            - /v2.0
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneAdmin, port]
+      KeystoneEC2:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneInternal, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneInternal, port]
+            - /v2.0/ec2tokens
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneInternal, port]
+      KeystoneInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneInternal, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneInternal, port]
+            - /v2.0
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneInternal, port]
+      KeystonePublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystonePublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystonePublic, port]
+        protocol:
+          get_param: [EndpointMap, KeystonePublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystonePublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystonePublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystonePublic, port]
+            - /v2.0
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystonePublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystonePublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystonePublic, port]
+      KeystoneV3Admin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneV3Admin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneV3Admin, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneV3Admin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Admin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Admin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Admin, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Admin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Admin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystoneAdminApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Admin, port]
+      KeystoneV3Internal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneV3Internal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneV3Internal, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneV3Internal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Internal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Internal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Internal, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Internal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Internal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: KeystonePublicApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Internal, port]
+      KeystoneV3Public:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, KeystoneV3Public, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, KeystoneV3Public, port]
+        protocol:
+          get_param: [EndpointMap, KeystoneV3Public, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Public, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Public, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Public, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, KeystoneV3Public, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, KeystoneV3Public, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, KeystoneV3Public, port]
+      NeutronAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NeutronAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NeutronAdmin, port]
+        protocol:
+          get_param: [EndpointMap, NeutronAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronAdmin, port]
+      NeutronInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NeutronInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NeutronInternal, port]
+        protocol:
+          get_param: [EndpointMap, NeutronInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronInternal, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NeutronApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronInternal, port]
+      NeutronPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NeutronPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, NeutronPublic, port]
+        protocol:
+          get_param: [EndpointMap, NeutronPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronPublic, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NeutronPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NeutronPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NeutronPublic, port]
+      NovaAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaAdmin, port]
+        protocol:
+          get_param: [EndpointMap, NovaAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaAdmin, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaAdmin, port]
+      NovaInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaInternal, port]
+        protocol:
+          get_param: [EndpointMap, NovaInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaInternal, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaInternal, port]
+      NovaPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaPublic, port]
+        protocol:
+          get_param: [EndpointMap, NovaPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaPublic, port]
+            - /v2/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaPublic, port]
+      NovaV3Admin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaAdmin, port]
+        protocol:
+          get_param: [EndpointMap, NovaAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaAdmin, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaAdmin, port]
+      NovaV3Internal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaInternal, port]
+        protocol:
+          get_param: [EndpointMap, NovaInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaInternal, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaInternal, port]
+      NovaV3Public:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaPublic, port]
+        protocol:
+          get_param: [EndpointMap, NovaPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaPublic, port]
+            - /v3
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaPublic, port]
+      NovaEC2Admin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaEC2Admin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaEC2Admin, port]
+        protocol:
+          get_param: [EndpointMap, NovaEC2Admin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Admin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Admin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Admin, port]
+            - /services/Admin
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Admin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Admin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Admin, port]
+      NovaEC2Internal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaEC2Internal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: NovaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaEC2Internal, port]
+        protocol:
+          get_param: [EndpointMap, NovaEC2Internal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Internal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Internal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Internal, port]
+            - /services/Cloud
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Internal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Internal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: NovaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Internal, port]
+      NovaEC2Public:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, NovaEC2Public, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, NovaEC2Public, port]
+        protocol:
+          get_param: [EndpointMap, NovaEC2Public, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Public, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Public, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Public, port]
+            - /services/Cloud
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, NovaEC2Public, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, NovaEC2Public, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, NovaEC2Public, port]
+      SaharaAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SaharaAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, SaharaAdmin, port]
+        protocol:
+          get_param: [EndpointMap, SaharaAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaAdmin, port]
+            - /v1.1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaAdmin, port]
+      SaharaInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SaharaInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, SaharaInternal, port]
+        protocol:
+          get_param: [EndpointMap, SaharaInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaInternal, port]
+            - /v1.1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaInternal, port]
+      SaharaPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SaharaPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+        port:
+          get_param: [EndpointMap, SaharaPublic, port]
+        protocol:
+          get_param: [EndpointMap, SaharaPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaPublic, port]
+            - /v1.1/%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SaharaPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SaharaPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SaharaApiVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SaharaPublic, port]
+      SwiftAdmin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftAdmin, port]
+        protocol:
+          get_param: [EndpointMap, SwiftAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftAdmin, port]
+      SwiftInternal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftInternal, port]
+        protocol:
+          get_param: [EndpointMap, SwiftInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftInternal, port]
+            - /v1/AUTH_%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftInternal, port]
+      SwiftPublic:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftPublic, port]
+        protocol:
+          get_param: [EndpointMap, SwiftPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftPublic, port]
+            - /v1/AUTH_%(tenant_id)s
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftPublic, port]
+      SwiftS3Admin:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftAdmin, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftAdmin, port]
+        protocol:
+          get_param: [EndpointMap, SwiftAdmin, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftAdmin, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftAdmin, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftAdmin, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftAdmin, port]
+      SwiftS3Internal:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftInternal, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftInternal, port]
+        protocol:
+          get_param: [EndpointMap, SwiftInternal, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftInternal, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftInternal, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftInternal, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: SwiftProxyVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftInternal, port]
+      SwiftS3Public:
+        host:
+          str_replace:
+            template:
+              get_param: [EndpointMap, SwiftPublic, host]
+            params:
+              CLOUDNAME: {get_param: CloudName}
+              IP_ADDRESS: {get_param: PublicVirtualIP}
+        port:
+          get_param: [EndpointMap, SwiftPublic, port]
+        protocol:
+          get_param: [EndpointMap, SwiftPublic, protocol]
+        uri:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftPublic, port]
+        uri_no_suffix:
+          list_join:
+          - ''
+          - - get_param: [EndpointMap, SwiftPublic, protocol]
+            - ://
+            - str_replace:
+                template:
+                  get_param: [EndpointMap, SwiftPublic, host]
+                params:
+                  CLOUDNAME: {get_param: CloudName}
+                  IP_ADDRESS: {get_param: PublicVirtualIP}
+            - ':'
+            - get_param: [EndpointMap, SwiftPublic, port]
index 7288aba..2601369 100644 (file)
@@ -116,7 +116,6 @@ resource_registry:
   OS::TripleO::BlockStorage::Ports::ManagementPort: network/ports/noop.yaml
 
   # Service Endpoint Mappings
-  OS::TripleO::Endpoint: network/endpoints/endpoint.yaml
   OS::TripleO::EndpointMap: network/endpoints/endpoint_map.yaml
 
   # validation resources