Browse Source

Add sanity_check for removing filepath and migrate htpasswd

This commit ensures that the filename and it's variations
are removed from any HTPasswdPasswordIdentityProvider
if openshift_master_manage_htpasswd == False.  If
openshift_master_manage_htpasswd is False, we do not manage
the htpasswd file and it may be managed by a user's own automated
process outside of openshift-ansible.  We need to fail and inform
user that the file needs to be moved so they can update their
processes.

In cases where we manage an htpasswd file, we will
hardcode 'filename' to '/etc/origin/master/htpasswd'
for all new installs and upgrades.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1565447
Michael Gugino 7 years ago
parent
commit
4871beff2a

+ 11 - 0
playbooks/init/basic_facts.yml

@@ -96,6 +96,17 @@
       - l_existing_config_master_config.projectConfig.defaultNodeSelector is defined
       - l_existing_config_master_config.projectConfig.defaultNodeSelector != ''
 
+    - set_fact:
+        # Take list of existing IDProviders so we can use/modify them later,
+        # especially for migrating htpasswd file.
+        openshift_master_existing_idproviders: "{{ l_existing_config_master_config.oauthConfig.identityProviders }}"
+      vars:
+        l_existing_config_master_config: "{{ (openshift_master_config_encoded_contents.content | b64decode | from_yaml) }}"
+      when:
+      - master_config_path_check.stat.exists
+      - l_existing_config_master_config.oauthConfig is defined
+      - l_existing_config_master_config.oauthConfig.identityProviders is defined
+
   - set_fact:
       # We need to setup openshift_client_binary here for special uses of delegate_to in
       # later roles and plays.

+ 29 - 0
roles/lib_utils/action_plugins/sanity_checks.py

@@ -219,6 +219,34 @@ class ActionModule(ActionBase):
                     ''.format(storage))
         return None
 
+    def check_htpasswd_provider(self, hostvars, host):
+        """Fails if openshift_master_identity_providers contains an entry of
+        kind HTPasswdPasswordIdentityProvider and
+        openshift_master_manage_htpasswd is False"""
+
+        idps = self.template_var(
+            hostvars, host, 'openshift_master_identity_providers')
+        if not idps:
+            # If we don't find any identity_providers, nothing for us to do.
+            return None
+        manage_pass = self.template_var(
+            hostvars, host, 'openshift_master_manage_htpasswd')
+        if to_bool(manage_pass):
+            # If we manage the file, we can just generate in the new path.
+            return None
+        old_keys = ('file', 'fileName', 'file_name', 'filename')
+        for idp in idps:
+            if idp['kind'] == 'HTPasswdPasswordIdentityProvider':
+                for old_key in old_keys:
+                    if old_key in idp is not None:
+                        raise errors.AnsibleModuleError(
+                            'openshift_master_identity_providers contains a '
+                            'provider of kind==HTPasswdPasswordIdentityProvider '
+                            'and {} is set.  Please migrate your htpasswd '
+                            'files to /etc/origin/master/htpasswd and update your '
+                            'existing master configs, and remove the {} key'
+                            'before proceeding.'.format(old_key, old_key))
+
     def run_checks(self, hostvars, host):
         """Execute the hostvars validations against host"""
         distro = self.template_var(hostvars, host, 'ansible_distribution')
@@ -231,6 +259,7 @@ class ActionModule(ActionBase):
         self.check_supported_ocp_version(hostvars, host, odt)
         self.check_session_auth_secrets(hostvars, host)
         self.check_unsupported_nfs_configs(hostvars, host)
+        self.check_htpasswd_provider(hostvars, host)
 
     def run(self, tmp=None, task_vars=None):
         result = super(ActionModule, self).run(tmp, task_vars)

+ 16 - 0
roles/lib_utils/filter_plugins/oo_filters.py

@@ -691,6 +691,21 @@ def lib_utils_oo_etcd_host_urls(hosts, use_ssl=True, port='2379'):
     return urls
 
 
+def lib_utils_mutate_htpass_provider(idps):
+    '''Updates identityProviders list to mutate filename of htpasswd auth
+    to hardcode filename = /etc/origin/master/htpasswd'''
+    old_keys = ('file', 'fileName', 'file_name')
+    for idp in idps:
+        if 'provider' in idp:
+            idp_p = idp['provider']
+            if idp_p['kind'] == 'HTPasswdPasswordIdentityProvider':
+                for old_key in old_keys:
+                    if old_key in idp_p:
+                        idp_p.pop(old_key)
+                idp_p['filename'] = '/etc/origin/master/htpasswd'
+    return idps
+
+
 class FilterModule(object):
     """ Custom ansible filter mapping """
 
@@ -725,4 +740,5 @@ class FilterModule(object):
             "map_from_pairs": map_from_pairs,
             "map_to_pairs": map_to_pairs,
             "lib_utils_oo_etcd_host_urls": lib_utils_oo_etcd_host_urls,
+            "lib_utils_mutate_htpass_provider": lib_utils_mutate_htpass_provider,
         }

+ 1 - 0
roles/lib_utils/filter_plugins/openshift_master.py

@@ -278,6 +278,7 @@ class HTPasswdPasswordIdentityProvider(IdentityProviderBase):
         idp['filename'] = '/etc/origin/master/htpasswd'
         super(HTPasswdPasswordIdentityProvider, self).__init__(api_version, idp)
         self._allow_additional = False
+        self._required += [['filename']]
 
     @staticmethod
     def get_default(key):

+ 18 - 0
roles/openshift_control_plane/tasks/migrate_idproviders.yml

@@ -0,0 +1,18 @@
+---
+# This file is to update htpass_provider filename path as it now must be
+# hard-coded to /etc/origin/master/htpasswd
+
+# Recreate the htpass file in the new location.
+- import_tasks: htpass_provider.yml
+
+# lib_utils_mutate_htpass_provider is a customer filter in
+# roles/lib_utils/filter_plugins/oo_filters.py
+- name: modify master id providers
+  yedit:
+    src: /etc/origin/master/master-config.yaml
+    edits:
+    - key: oauthConfig.identityProviders
+      value: "{{ openshift_master_existing_idproviders | lib_utils_mutate_htpass_provider }}"
+  when:
+  - openshift_master_existing_idproviders is defined
+  - openshift_master_manage_htpasswd

+ 3 - 0
roles/openshift_control_plane/tasks/upgrade.yml

@@ -8,6 +8,9 @@
   - "{{ openshift_service_type }}-master-controllers"
   failed_when: false
 
+# Only needed for 3.10, remove in 3.11.
+- import_tasks: migrate_idproviders.yml
+
 - import_tasks: static_shim.yml
 
 - import_tasks: upgrade/upgrade_scheduler.yml