diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 7949319dba..4d36e2cd71 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -288,11 +288,9 @@ public OpenSearchSecurityPlugin(final Settings settings, final Path configPath) transportPassiveAuthSetting = new TransportPassiveAuthSetting(settings); - System.out.println("Checking is default password is empty"); if (settings.get(ConfigConstants.SECURITY_BOOTSTRAP_ADMIN_DEFAULT_PASSWORD) == null) { throw new RuntimeException("A default admin password must be provided in the opensearch.yml file."); } - System.out.println("Default password is not empty"); if (disabled) { this.sslCertReloadEnabled = false; @@ -1014,11 +1012,7 @@ public Collection createComponents( adminDns = new AdminDNs(settings); - try { - cr = ConfigurationRepository.create(settings, this.configPath, threadPool, localClient, clusterService, auditLog); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + cr = ConfigurationRepository.create(settings, this.configPath, threadPool, localClient, clusterService, auditLog); userService = new UserService(cs, cr, settings, localClient); diff --git a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java index 011be46a05..24e85b1307 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java @@ -49,7 +49,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.ExceptionsHelper; @@ -63,7 +62,6 @@ import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.metadata.MappingMetadata; import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.SetOnce; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.common.util.concurrent.ThreadContext.StoredContext; @@ -102,18 +100,17 @@ public class ConfigurationRepository { private final AtomicBoolean installDefaultConfig = new AtomicBoolean(); private final boolean acceptInvalid; - private ConfigurationRepository( - Settings settings, - final Path configPath, - ThreadPool threadPool, - Client client, - ClusterService clusterService, - AuditLog auditLog - ) throws InterruptedException { + Settings settings, + final Path configPath, + ThreadPool threadPool, + Client client, + ClusterService clusterService, + AuditLog auditLog + ) { this.securityIndex = settings.get( - ConfigConstants.SECURITY_CONFIG_INDEX_NAME, - ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX + ConfigConstants.SECURITY_CONFIG_INDEX_NAME, + ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX ); this.settings = settings; this.client = client; @@ -140,8 +137,8 @@ private ConfigurationRepository( try { String lookupDir = System.getProperty("security.default_init.dir"); final String cd = lookupDir != null - ? (lookupDir + "/") - : new Environment(settings, configPath).configDir().toAbsolutePath().toString() + "/opensearch-security/"; + ? (lookupDir + "/") + : new Environment(settings, configPath).configDir().toAbsolutePath().toString() + "/opensearch-security/"; File confFile = new File(cd + "config.yml"); if (confFile.exists()) { final ThreadContext threadContext = threadPool.getThreadContext(); @@ -154,60 +151,59 @@ private ConfigurationRepository( ConfigHelper.uploadFile(client, cd + "config.yml", securityIndex, CType.CONFIG, DEFAULT_CONFIG_VERSION); ConfigHelper.uploadFile(client, cd + "roles.yml", securityIndex, CType.ROLES, DEFAULT_CONFIG_VERSION); ConfigHelper.uploadFile( - client, - cd + "roles_mapping.yml", - securityIndex, - CType.ROLESMAPPING, - DEFAULT_CONFIG_VERSION + client, + cd + "roles_mapping.yml", + securityIndex, + CType.ROLESMAPPING, + DEFAULT_CONFIG_VERSION ); - System.out.println("Overwriting with internal users yaml"); ConfigHelper.uploadFile( - client, - cd + "internal_users.yml", - securityIndex, - CType.INTERNALUSERS, - DEFAULT_CONFIG_VERSION + client, + cd + "internal_users.yml", + securityIndex, + CType.INTERNALUSERS, + DEFAULT_CONFIG_VERSION ); ConfigHelper.uploadFile( - client, - cd + "action_groups.yml", - securityIndex, - CType.ACTIONGROUPS, - DEFAULT_CONFIG_VERSION + client, + cd + "action_groups.yml", + securityIndex, + CType.ACTIONGROUPS, + DEFAULT_CONFIG_VERSION ); if (DEFAULT_CONFIG_VERSION == 2) { ConfigHelper.uploadFile( - client, - cd + "tenants.yml", - securityIndex, - CType.TENANTS, - DEFAULT_CONFIG_VERSION + client, + cd + "tenants.yml", + securityIndex, + CType.TENANTS, + DEFAULT_CONFIG_VERSION ); } final boolean populateEmptyIfFileMissing = true; ConfigHelper.uploadFile( - client, - cd + "nodes_dn.yml", - securityIndex, - CType.NODESDN, - DEFAULT_CONFIG_VERSION, - populateEmptyIfFileMissing + client, + cd + "nodes_dn.yml", + securityIndex, + CType.NODESDN, + DEFAULT_CONFIG_VERSION, + populateEmptyIfFileMissing ); ConfigHelper.uploadFile( - client, - cd + "whitelist.yml", - securityIndex, - CType.WHITELIST, - DEFAULT_CONFIG_VERSION, - populateEmptyIfFileMissing + client, + cd + "whitelist.yml", + securityIndex, + CType.WHITELIST, + DEFAULT_CONFIG_VERSION, + populateEmptyIfFileMissing ); ConfigHelper.uploadFile( - client, - cd + "allowlist.yml", - securityIndex, - CType.ALLOWLIST, - DEFAULT_CONFIG_VERSION, - populateEmptyIfFileMissing + client, + cd + "allowlist.yml", + securityIndex, + CType.ALLOWLIST, + DEFAULT_CONFIG_VERSION, + populateEmptyIfFileMissing ); // audit.yml is not packaged by default @@ -244,8 +240,8 @@ private ConfigurationRepository( final Set deprecatedAuditKeysInSettings = AuditConfig.getDeprecatedKeys(settings); if (!deprecatedAuditKeysInSettings.isEmpty()) { LOGGER.warn( - "Following keys {} are deprecated in opensearch settings. They will be removed in plugin v2.0.0.0", - deprecatedAuditKeysInSettings + "Following keys {} are deprecated in opensearch settings. They will be removed in plugin v2.0.0.0", + deprecatedAuditKeysInSettings ); } final boolean isAuditConfigDocPresentInIndex = cl.isAuditConfigDocPresentInIndex(); @@ -256,7 +252,7 @@ private ConfigurationRepository( LOGGER.info("Hot-reloading of audit configuration is enabled"); } else { LOGGER.info( - "Hot-reloading of audit configuration is disabled. Using configuration with defaults from opensearch settings. Populate the configuration in index using audit.yml or securityadmin to enable it." + "Hot-reloading of audit configuration is disabled. Using configuration with defaults from opensearch settings. Populate the configuration in index using audit.yml or securityadmin to enable it." ); auditLog.setConfig(AuditConfig.from(settings)); } @@ -269,7 +265,6 @@ private ConfigurationRepository( try { createAdminUser(); - System.out.println("After creating admin user, internal users config is: " + getConfiguration(CType.INTERNALUSERS).getCEntries()); } catch (IOException | PrivilegedActionException e) { throw new RuntimeException(e); } @@ -295,18 +290,18 @@ private void waitForSecurityIndexToBeAtLeastYellow() { ClusterHealthResponse response = null; try { response = client.admin() - .cluster() - .health(new ClusterHealthRequest(securityIndex).waitForActiveShards(1).waitForYellowStatus()) - .actionGet(); + .cluster() + .health(new ClusterHealthRequest(securityIndex).waitForActiveShards(1).waitForYellowStatus()) + .actionGet(); } catch (Exception e) { LOGGER.debug("Caught a {} but we just try again ...", e.toString()); } while (response == null || response.isTimedOut() || response.getStatus() == ClusterHealthStatus.RED) { LOGGER.debug( - "index '{}' not healthy yet, we try again ... (Reason: {})", - securityIndex, - response == null ? "no response" : (response.isTimedOut() ? "timeout" : "other, maybe red cluster") + "index '{}' not healthy yet, we try again ... (Reason: {})", + securityIndex, + response == null ? "no response" : (response.isTimedOut() ? "timeout" : "other, maybe red cluster") ); try { Thread.sleep(500); @@ -330,14 +325,14 @@ public void initOnNodeStart() { bgThread.start(); } else if (settings.getAsBoolean(ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST, true)) { LOGGER.info( - "Will not attempt to create index {} and default configs if they are absent. Use securityadmin to initialize cluster", - securityIndex + "Will not attempt to create index {} and default configs if they are absent. Use securityadmin to initialize cluster", + securityIndex ); bgThread.start(); } else { LOGGER.info( - "Will not attempt to create index {} and default configs if they are absent. Will not perform background initialization", - securityIndex + "Will not attempt to create index {} and default configs if they are absent. Will not perform background initialization", + securityIndex ); } } catch (Throwable e2) { @@ -351,22 +346,14 @@ public boolean isAuditHotReloadingEnabled() { } public static ConfigurationRepository create( - Settings settings, - final Path configPath, - final ThreadPool threadPool, - Client client, - ClusterService clusterService, - AuditLog auditLog - ) throws InterruptedException { - final ConfigurationRepository repository = new ConfigurationRepository( - settings, - configPath, - threadPool, - client, - clusterService, - auditLog - ); - return repository; + Settings settings, + final Path configPath, + final ThreadPool threadPool, + Client client, + ClusterService clusterService, + AuditLog auditLog + ) { + return new ConfigurationRepository(settings, configPath, threadPool, client, clusterService, auditLog); } public void setDynamicConfigFactory(DynamicConfigFactory dynamicConfigFactory) { @@ -377,7 +364,6 @@ public void setDynamicConfigFactory(DynamicConfigFactory dynamicConfigFactory) { * @return can also return empty in case it was never loaded */ public SecurityDynamicConfiguration getConfiguration(CType configurationType) { - System.out.println("Getting configuration"); SecurityDynamicConfiguration conf = configCache.getIfPresent(configurationType); if (conf != null) { return conf.deepClone(); @@ -388,7 +374,6 @@ public SecurityDynamicConfiguration getConfiguration(CType configurationType) private final Lock LOCK = new ReentrantLock(); public void reloadConfiguration(Collection configTypes) throws ConfigUpdateAlreadyInProgressException { - System.out.println("Reloading configuration(s) with config types: " + Arrays.stream(configTypes.toArray()).map(Object::toString).collect(Collectors.joining(","))); try { if (LOCK.tryLock(60, TimeUnit.SECONDS)) { try { @@ -416,7 +401,6 @@ public synchronized void subscribeOnChange(ConfigurationChangeListener listener) } private synchronized void notifyAboutChanges(Map> typeToConfig) { - System.out.println("Notifying about changes"); for (ConfigurationChangeListener listener : configurationChangedListener) { try { LOGGER.debug("Notify {} listener about change configuration with type {}", listener); @@ -432,17 +416,16 @@ private synchronized void notifyAboutChanges(Map> getConfigurationsFromIndex( - Collection configTypes, - boolean logComplianceEvent + Collection configTypes, + boolean logComplianceEvent ) { - System.out.println("Getting configuration from index"); return getConfigurationsFromIndex(configTypes, logComplianceEvent, this.acceptInvalid); } public Map> getConfigurationsFromIndex( - Collection configTypes, - boolean logComplianceEvent, - boolean acceptInvalid + Collection configTypes, + boolean logComplianceEvent, + boolean acceptInvalid ) { final ThreadContext threadContext = threadPool.getThreadContext(); @@ -461,14 +444,14 @@ public Map> getConfigurationsFromIndex( LOGGER.debug("security index exists and was created with ES 7 (new layout)"); } retVal.putAll( - validate(cl.load(configTypes.toArray(new CType[0]), 10, TimeUnit.SECONDS, acceptInvalid), configTypes.size()) + validate(cl.load(configTypes.toArray(new CType[0]), 10, TimeUnit.SECONDS, acceptInvalid), configTypes.size()) ); } else { // wait (and use new layout) LOGGER.debug("security index not exists (yet)"); retVal.putAll( - validate(cl.load(configTypes.toArray(new CType[0]), 10, TimeUnit.SECONDS, acceptInvalid), configTypes.size()) + validate(cl.load(configTypes.toArray(new CType[0]), 10, TimeUnit.SECONDS, acceptInvalid), configTypes.size()) ); } @@ -487,7 +470,7 @@ public Map> getConfigurationsFromIndex( } private Map> validate(Map> conf, int expectedSize) - throws InvalidConfigException { + throws InvalidConfigException { if (conf == null || conf.size() != expectedSize) { throw new InvalidConfigException("Retrieved only partial configuration"); @@ -504,26 +487,23 @@ public static int getDefaultConfigVersion() { return ConfigurationRepository.DEFAULT_CONFIG_VERSION; } - private void createAdminUser() throws IOException, PrivilegedActionException { String plaintextPassword = this.settings.get(ConfigConstants.SECURITY_BOOTSTRAP_ADMIN_DEFAULT_PASSWORD); String hashedPassword = hash(plaintextPassword.toCharArray()); - String userJsonAsString = "{ \"hash\" : \"" + hashedPassword + "\", \"backend_roles\": [\"admin\"], " - + "\"attributes\": { \"service\": \"false\", " - + "\"enabled\": \"false\"}" - + " }\n"; + String userJsonAsString = "{ \"hash\" : \"" + + hashedPassword + + "\", \"backend_roles\": [\"admin\"], " + + "\"attributes\": { \"service\": \"false\", " + + "\"enabled\": \"false\"}" + + " }\n"; JsonNode accountInfo = DefaultObjectMapper.readTree(userJsonAsString); ObjectNode account = (ObjectNode) accountInfo; SecurityDynamicConfiguration sdc = getConfiguration(CType.INTERNALUSERS); if (!sdc.exists("admin")) { - System.out.println("Admin user not present so setting to new account: " + account.toPrettyString()); - sdc.putCObject( - "admin", - DefaultObjectMapper.readTree(account, sdc.getImplementingClass()) - ); + sdc.putCObject("admin", DefaultObjectMapper.readTree(account, sdc.getImplementingClass())); } ConfigHelper.updateConfig(securityIndex, client, CType.INTERNALUSERS, sdc); reloadConfiguration(Collections.singleton(CType.INTERNALUSERS)); diff --git a/src/main/java/org/opensearch/security/support/ConfigHelper.java b/src/main/java/org/opensearch/security/support/ConfigHelper.java index 0b3c6dcbdc..c87481e790 100644 --- a/src/main/java/org/opensearch/security/support/ConfigHelper.java +++ b/src/main/java/org/opensearch/security/support/ConfigHelper.java @@ -39,7 +39,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.opensearch.ExceptionsHelper; import org.opensearch.action.DocWriteRequest.OpType; import org.opensearch.action.index.IndexRequest; import org.opensearch.action.support.WriteRequest; @@ -195,23 +194,22 @@ public static SecurityDynamicConfiguration fromYamlString( return fromYamlReader(new StringReader(yamlString), ctype, version, seqNo, primaryTerm); } - public static void updateConfig(String indexName, Client tc, CType cType, final SecurityDynamicConfiguration configuration) throws VersionConflictEngineException, PrivilegedActionException { + public static void updateConfig(String indexName, Client tc, CType cType, final SecurityDynamicConfiguration configuration) + throws VersionConflictEngineException, PrivilegedActionException { - System.out.println("Updating config for " + cType + " in index " + indexName + " with seqNo " + configuration.getSeqNo() + " and primaryTerm " + configuration.getPrimaryTerm() + " and configVersion " + configuration.get_meta().getConfig_version() + " for index: " + indexName + ""); AccessController.doPrivileged((PrivilegedExceptionAction) () -> { final IndexRequest ir = new IndexRequest(indexName); final String id = cType.toLCString(); try { - System.out.println("Updating index with " + XContentHelper.toXContent(configuration, XContentType.JSON, true).utf8ToString()); tc.index( - ir.id(id) - .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .source(id, XContentHelper.toXContent(configuration, XContentType.JSON, false)) + ir.id(id) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(id, XContentHelper.toXContent(configuration, XContentType.JSON, false)) ); } catch (VersionConflictEngineException versionConflictEngineException) { - System.out.println("Index " + indexName + " already contains doc with id " + cType); + LOGGER.info("Index " + indexName + " already contains doc with id " + cType); } return null; }); diff --git a/src/test/java/org/opensearch/security/test/SingleClusterTest.java b/src/test/java/org/opensearch/security/test/SingleClusterTest.java index b104a672c6..e5ffb4fbf0 100644 --- a/src/test/java/org/opensearch/security/test/SingleClusterTest.java +++ b/src/test/java/org/opensearch/security/test/SingleClusterTest.java @@ -100,7 +100,9 @@ private Settings ccs(Settings nodeOverride) throws Exception { if (remoteClusterHelper != null) { Assert.assertNull("No remote clusters", remoteClusterInfo); remoteClusterInfo = remoteClusterHelper.startCluster(minimumSecuritySettings(Settings.EMPTY), ClusterConfiguration.SINGLENODE); - Settings.Builder builder = Settings.builder().put(nodeOverride).put("plugins.security.bootstrap.admin.password", "passwordForTests") + Settings.Builder builder = Settings.builder() + .put(nodeOverride) + .put("plugins.security.bootstrap.admin.password", "testPassword") .putList("cluster.remote.cross_cluster_two.seeds", remoteClusterInfo.nodeHost + ":" + remoteClusterInfo.nodePort); return builder.build(); } else {