UpgradeCatalog240 extends AbstractUpgradeCatalog { protected void updateKerberosConfigs() throws AmbariException { AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); Clusters clusters = ambariManagementController.getClusters(); Map<String, Cluster> clusterMap = getCheckedClusterMap(clusters); for (final Cluster cluster : clusterMap.values()) { Config config; String newDefault = null; AmbariMetaInfo metaInfo = ambariManagementController.getAmbariMetaInfo(); StackId stackId = cluster.getCurrentStackVersion(); StackInfo stackInfo = ((metaInfo == null) || (stackId == null)) ? null : metaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); if(stackInfo != null) { ServiceInfo kerberosService = stackInfo.getService("KERBEROS"); if (kerberosService != null) { List<PropertyInfo> properties = kerberosService.getProperties(); if (properties != null) { for (PropertyInfo propertyInfo : properties) { if ("krb5-conf.xml".equals(propertyInfo.getFilename()) && "content".equals(propertyInfo.getName())) { newDefault = propertyInfo.getValue(); break; } } } } } config = cluster.getDesiredConfigByType("kerberos-env"); if (config != null) { Map<String, String> updates = new HashMap<String, String>(); Set<String> removes = new HashSet<String>(); String value = config.getProperties().get("kdc_host"); updates.put("kdc_hosts", value); removes.add("kdc_host"); updates.put("create_ambari_principal", "false"); updateConfigurationPropertiesForCluster(cluster, "kerberos-env", updates, removes, true, false); } if(newDefault != null) { config = cluster.getDesiredConfigByType("krb5-conf"); if (config != null) { String value = config.getProperties().get("content"); String oldDefault = "\n[libdefaults]\n renew_lifetime = 7d\n forwardable = true\n default_realm = {{realm}}\n ticket_lifetime = 24h\n dns_lookup_realm = false\n dns_lookup_kdc = false\n #default_tgs_enctypes = {{encryption_types}}\n #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(\u0027,\u0027) %}\n {{domain}} = {{realm}}\n{% endfor %}\n{% endif %}\n\n[logging]\n default = FILE:/var/log/krb5kdc.log\n admin_server = FILE:/var/log/kadmind.log\n kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n {{realm}} = {\n admin_server = {{admin_server_host|default(kdc_host, True)}}\n kdc = {{kdc_host}}\n }\n\n{# Append additional realm declarations below #}"; if (oldDefault.equalsIgnoreCase(value)) { Map<String, String> updates = Collections.singletonMap("content", newDefault); updateConfigurationPropertiesForCluster(cluster, "krb5-conf", updates, null, true, false); } else { LOG.warn("The krb5-conf/content value was not updated to use the kerberos-env/kdc_hosts " + "property since the stored template appears to have been changed from the default. " + "This value should be manually updated so that\n" + "\tkdc = {{kdc_host}}\n" + "Is changed to something like\n" + "\t{%- if kdc_hosts &gt; 0 -%}\n" + "\t{%- set kdc_host_list = kdc_hosts.split(',') -%}\n" + "\t{%- if kdc_host_list -%}\n" + "\t{% for kdc_host in kdc_host_list %}\n" + "\t kdc = {{kdc_host|trim()}}\n" + "\t{%- endfor -%}"); } } } } } @Inject  UpgradeCatalog240(Injector injector); @Override String getTargetVersion(); @Override String getSourceVersion(); static final String DESIRED_VERSION_COLUMN_NAME; static final String BLUEPRINT_SETTING_TABLE; static final String BLUEPRINT_NAME_COL; static final String SETTING_NAME_COL; static final String SETTING_DATA_COL; static final String ID; static final String BLUEPRINT_TABLE; static final String VIEWINSTANCE_TABLE; static final String SHORT_URL_COLUMN; static final String CLUSTER_HANDLE_COLUMN; static final String REQUESTSCHEDULE_TABLE; static final String AUTHENTICATED_USER_ID_COLUMN; static final String TIMELINE_METRICS_SINK_COLLECTION_PERIOD; static final String ONE_DIR_PER_PARITION_PROPERTY; static final String VIEWURL_TABLE; static final String URL_ID_COLUMN; static final String PRECISION_TABLE_TTL_PROPERTY; static final String CLUSTER_SECOND_TABLE_TTL_PROPERTY; static final String CLUSTER_TYPE_COLUMN; static final String REMOTE_AMBARI_CLUSTER_TABLE; static final String REMOTE_AMBARI_CLUSTER_SERVICE_TABLE; static final String CLUSTER_ID; static final String SERVICE_NAME; static final String CLUSTER_NAME; }
@Test public void testUpdateKerberosConfigurationWithChangedKrb5ConfContent() throws Exception { final AmbariManagementController controller = createMock(AmbariManagementController.class); final AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class); final StackInfo stackInfo = createMock(StackInfo.class); final ServiceInfo serviceInfo = createMock(ServiceInfo.class); final DBAccessor dbAccessor = createNiceMock(DBAccessor.class); final OsFamily osFamily = createNiceMock(OsFamily.class); final Map<String, String> propertiesKerberosEnv = new HashMap<String, String>() { { put("realm", "EXAMPLE.COM"); put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5"); put("kdc_host", "c6407.ambari.apache.org"); put("admin_server_host", "c6407.ambari.apache.org"); put("kdc_type", "mit-kdc"); } }; final Map<String, String> propertiesKrb5Conf = new HashMap<String, String>() { { put("content", "CHANGED CONTENT"); } }; final Config configKerberosEnv = createNiceMock(Config.class); expect(configKerberosEnv.getProperties()).andReturn(propertiesKerberosEnv).anyTimes(); expect(configKerberosEnv.getTag()).andReturn("tag1").anyTimes(); final Config configKrb5Conf = createNiceMock(Config.class); expect(configKrb5Conf.getProperties()).andReturn(propertiesKrb5Conf).anyTimes(); expect(configKrb5Conf.getTag()).andReturn("tag1").anyTimes(); final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(configKerberosEnv).once(); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(configKrb5Conf).once(); final Clusters clusters = createNiceMock(Clusters.class); expect(clusters.getClusters()).andReturn(Collections.singletonMap("c1", cluster)); expect(controller.getClusters()).andReturn(clusters).once(); expect(controller.getAmbariMetaInfo()).andReturn(metaInfo).once(); final StackId currentStackVersion = new StackId("HDP", "2.4.2"); expect(metaInfo.getStack(currentStackVersion.getStackName(), currentStackVersion.getStackVersion())) .andReturn(stackInfo) .once(); expect(stackInfo.getService("KERBEROS")).andReturn(serviceInfo).once(); final PropertyInfo propertyInfo = new PropertyInfo(); propertyInfo.setFilename("krb5-conf.xml"); propertyInfo.setName("content"); propertyInfo.setValue("new content template"); expect(serviceInfo.getProperties()).andReturn(Collections.singletonList(propertyInfo)).once(); expect(cluster.getConfigsByType("kerberos-env")) .andReturn(Collections.singletonMap("tag1", configKerberosEnv)) .once(); expect(cluster.getDesiredConfigByType("kerberos-env")) .andReturn(configKerberosEnv) .once(); expect(cluster.getCurrentStackVersion()).andReturn(currentStackVersion).once(); Capture<Cluster> clusterCapture = newCapture(CaptureType.ALL); Capture<String> typeCapture = newCapture(CaptureType.ALL); Capture<Map<String, String>> propertiesCapture = newCapture(CaptureType.ALL); Capture<String> tagCapture = newCapture(CaptureType.ALL); Capture<Map<String, Map<String, String>>> attributesCapture = newCapture(CaptureType.ALL); expect(controller.createConfig(capture(clusterCapture), capture(typeCapture), capture(propertiesCapture), capture(tagCapture), capture(attributesCapture))) .andReturn(createNiceMock(Config.class)) .anyTimes(); replay(controller, metaInfo, stackInfo, serviceInfo, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters); final Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bind(AmbariManagementController.class).toInstance(controller); bind(DBAccessor.class).toInstance(dbAccessor); bind(OsFamily.class).toInstance(osFamily); bind(EntityManager.class).toInstance(entityManager); bind(PasswordEncoder.class).toInstance(createNiceMock(PasswordEncoder.class)); bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class)); bind(HookService.class).toInstance(createMock(HookService.class)); } }); injector.getInstance(UpgradeCatalog240.class).updateKerberosConfigs(); verify(controller, metaInfo, stackInfo, serviceInfo, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters); List<String> typeCaptureValues = typeCapture.getValues(); Assert.assertEquals(1, typeCaptureValues.size()); Assert.assertEquals("kerberos-env", typeCaptureValues.get(0)); List<Map<String, String>> propertiesCaptureValues = propertiesCapture.getValues(); Assert.assertEquals(1, propertiesCaptureValues.size()); Map<String, String> capturedCRProperties; capturedCRProperties = propertiesCaptureValues.get(0); Assert.assertNotNull(capturedCRProperties); Assert.assertFalse(capturedCRProperties.containsKey("kdc_host")); Assert.assertTrue(capturedCRProperties.containsKey("kdc_hosts")); Assert.assertTrue(capturedCRProperties.containsKey("create_ambari_principal")); for (String property : propertiesKerberosEnv.keySet()) { if ("kdc_host".equals(property)) { Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get("kdc_hosts")); } else if ("create_ambari_principal".equals(property)) { Assert.assertEquals(property, propertiesKerberosEnv.get(property), "false"); } else { Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get(property)); } } }