From 3a8b4f1315e28f35e16ace77560f040f08588722 Mon Sep 17 00:00:00 2001
From: Andrew Butcher <abutcher@redhat.com>
Date: Tue, 3 Nov 2015 11:26:33 -0500
Subject: Filter internal hostnames from the list of parsed names.

---
 filter_plugins/oo_filters.py                       | 16 +++++++++++++---
 inventory/byo/hosts.example                        |  2 ++
 playbooks/common/openshift-master/config.yml       |  2 +-
 roles/openshift_facts/library/openshift_facts.py   | 14 +++++++++++---
 roles/openshift_master/templates/master.yaml.v1.j2 |  2 +-
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/filter_plugins/oo_filters.py b/filter_plugins/oo_filters.py
index d653b9217..dfd9a111e 100644
--- a/filter_plugins/oo_filters.py
+++ b/filter_plugins/oo_filters.py
@@ -330,7 +330,8 @@ class FilterModule(object):
         return revamped_outputs
 
     @staticmethod
-    def oo_parse_certificate_names(certificates, data_dir):
+    # pylint: disable=too-many-branches
+    def oo_parse_certificate_names(certificates, data_dir, internal_hostnames):
         ''' Parses names from list of certificate hashes.
 
             Ex: certificates = [{ "certfile": "/etc/origin/master/custom1.crt",
@@ -352,6 +353,9 @@ class FilterModule(object):
         if not issubclass(type(data_dir), unicode):
             raise errors.AnsibleFilterError("|failed expects data_dir is unicode")
 
+        if not issubclass(type(internal_hostnames), list):
+            raise errors.AnsibleFilterError("|failed expects internal_hostnames is list")
+
         for certificate in certificates:
             if 'names' in certificate.keys():
                 continue
@@ -364,7 +368,7 @@ class FilterModule(object):
                 certificate['keyfile'] = os.path.join(data_dir, certificate['keyfile'])
                 if not os.path.isfile(certificate['certfile']) and not os.path.isfile(certificate['keyfile']):
                     # Unable to find cert/key in data_dir
-                    raise errors.AnsibleFilterError("|certificate and/or key does not exist %s, %s" %
+                    raise errors.AnsibleFilterError("|certificate and/or key does not exist '%s', '%s'" %
                                                     (certificate['certfile'], certificate['keyfile']))
 
             try:
@@ -376,9 +380,15 @@ class FilterModule(object):
                         for name in str(cert.get_extension(i)).replace('DNS:', '').split(', '):
                             certificate['names'].append(name)
             except:
-                raise errors.AnsibleFilterError("|failed to parse certificate %s" % certificate['certfile'])
+                raise errors.AnsibleFilterError(("|failed to parse certificate '%s', " % certificate['certfile'] +
+                                                 "please specify certificate names in host inventory"))
 
+            certificate['names'] = [name for name in certificate['names'] if name not in internal_hostnames]
             certificate['names'] = list(set(certificate['names']))
+            if not certificate['names']:
+                raise errors.AnsibleFilterError(("|failed to parse certificate '%s' or " % certificate['certfile'] +
+                                                 "detected a collision with internal hostname, please specify " +
+                                                 "certificate names in host inventory"))
         return certificates
 
     def filters(self):
diff --git a/inventory/byo/hosts.example b/inventory/byo/hosts.example
index c6733567a..f60918e6d 100644
--- a/inventory/byo/hosts.example
+++ b/inventory/byo/hosts.example
@@ -101,6 +101,8 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 
 # Configure custom master certificates
 #openshift_master_named_certificates=[{"certfile": "/path/to/custom1.crt", "keyfile": "/path/to/custom1.key"}]
+# Detected names may be overridden by specifying the "names" key
+#openshift_master_named_certificates=[{"certfile": "/path/to/custom1.crt", "keyfile": "/path/to/custom1.key", "names": ["public-master-host.com"]}]
 
 # host group for masters
 [masters]
diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml
index 4662c179a..59c4b2370 100644
--- a/playbooks/common/openshift-master/config.yml
+++ b/playbooks/common/openshift-master/config.yml
@@ -204,7 +204,7 @@
   tasks:
   - name: Collect certificate names
     set_fact:
-      parsed_named_certificates: "{{ openshift_master_named_certificates | oo_parse_certificate_names(master_cert_config_dir) }}"
+      parsed_named_certificates: "{{ openshift_master_named_certificates | oo_parse_certificate_names(master_cert_config_dir, openshift.common.internal_hostnames) }}"
     when: openshift_master_named_certificates is defined
 
 - name: Configure master instances
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index 163e67f62..28866bd48 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -484,12 +484,16 @@ def set_aggregate_facts(facts):
             dict: the facts dict updated with aggregated facts
     """
     all_hostnames = set()
+    internal_hostnames = set()
     if 'common' in facts:
         all_hostnames.add(facts['common']['hostname'])
         all_hostnames.add(facts['common']['public_hostname'])
         all_hostnames.add(facts['common']['ip'])
         all_hostnames.add(facts['common']['public_ip'])
 
+        internal_hostnames.add(facts['common']['hostname'])
+        internal_hostnames.add(facts['common']['ip'])
+
         if 'master' in facts:
             # FIXME: not sure why but facts['dns']['domain'] fails
             cluster_domain = 'cluster.local'
@@ -497,13 +501,17 @@ def set_aggregate_facts(facts):
                 all_hostnames.add(facts['master']['cluster_hostname'])
             if 'cluster_public_hostname' in facts['master']:
                 all_hostnames.add(facts['master']['cluster_public_hostname'])
-            all_hostnames.update(['openshift', 'openshift.default', 'openshift.default.svc',
-                                  'openshift.default.svc.' + cluster_domain, 'kubernetes', 'kubernetes.default',
-                                  'kubernetes.default.svc', 'kubernetes.default.svc.' + cluster_domain])
+            svc_names = ['openshift', 'openshift.default', 'openshift.default.svc',
+                         'openshift.default.svc.' + cluster_domain, 'kubernetes', 'kubernetes.default',
+                         'kubernetes.default.svc', 'kubernetes.default.svc.' + cluster_domain]
+            all_hostnames.update(svc_names)
+            internal_hostnames.update(svc_names)
             first_svc_ip = str(IPNetwork(facts['master']['portal_net'])[1])
             all_hostnames.add(first_svc_ip)
+            internal_hostnames.add(first_svc_ip)
 
         facts['common']['all_hostnames'] = list(all_hostnames)
+        facts['common']['internal_hostnames'] = list(all_hostnames)
 
     return facts
 
diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2
index b429be596..9547a6945 100644
--- a/roles/openshift_master/templates/master.yaml.v1.j2
+++ b/roles/openshift_master/templates/master.yaml.v1.j2
@@ -16,7 +16,7 @@ assetConfig:
     maxRequestsInFlight: 0
     requestTimeoutSeconds: 0
 corsAllowedOrigins:
-{% for origin in ['127.0.0.1', 'localhost', openshift.common.hostname, openshift.common.ip, openshift.common.public_hostname, openshift.common.public_ip] %}
+{% for origin in ['127.0.0.1', 'localhost', openshift.common.hostname, openshift.common.ip, openshift.common.public_hostname, openshift.common.public_ip] | unique %}
   - {{ origin }}
 {% endfor %}
 {% for custom_origin in openshift.master.custom_cors_origins | default("") %}
-- 
cgit v1.2.3