diff --git a/common/src/main/java/io/druid/metadata/EnvironmentVariablePasswordProvider.java b/common/src/main/java/io/druid/metadata/EnvironmentVariablePasswordProvider.java new file mode 100644 index 00000000000..71730ef59da --- /dev/null +++ b/common/src/main/java/io/druid/metadata/EnvironmentVariablePasswordProvider.java @@ -0,0 +1,81 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.druid.metadata; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Preconditions; + +public class EnvironmentVariablePasswordProvider implements PasswordProvider +{ + private final String variable; + + @JsonCreator + public EnvironmentVariablePasswordProvider( + @JsonProperty("variable") String variable + ) + { + this.variable = Preconditions.checkNotNull(variable); + } + + @JsonProperty("variable") + public String getVariable() + { + return variable; + } + + @JsonIgnore + @Override + public String getPassword() + { + return System.getenv(variable); + } + + @Override + public String toString() + { + return "EnvironmentVariablePasswordProvider{" + + "variable='" + variable + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + EnvironmentVariablePasswordProvider that = (EnvironmentVariablePasswordProvider) o; + + return variable != null ? variable.equals(that.variable) : that.variable == null; + + } + + @Override + public int hashCode() + { + return variable != null ? variable.hashCode() : 0; + } +} diff --git a/common/src/main/java/io/druid/metadata/PasswordProvider.java b/common/src/main/java/io/druid/metadata/PasswordProvider.java index 9e529108630..7d8292a2bf6 100644 --- a/common/src/main/java/io/druid/metadata/PasswordProvider.java +++ b/common/src/main/java/io/druid/metadata/PasswordProvider.java @@ -26,11 +26,13 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; /** * Implement this for different ways to (optionally securely) access db passwords. */ -@JsonTypeInfo(use= JsonTypeInfo.Id.NAME, property="type", defaultImpl = DefaultPasswordProvider.class) -@JsonSubTypes(value={ - @JsonSubTypes.Type(name="default", value=DefaultPasswordProvider.class), +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = DefaultPasswordProvider.class) +@JsonSubTypes(value = { + @JsonSubTypes.Type(name = "default", value = DefaultPasswordProvider.class), + @JsonSubTypes.Type(name = "environment", value = EnvironmentVariablePasswordProvider.class), + }) -public interface PasswordProvider +public interface PasswordProvider { public String getPassword(); } diff --git a/common/src/test/java/io/druid/metadata/EnvironmentVariablePasswordProviderTest.java b/common/src/test/java/io/druid/metadata/EnvironmentVariablePasswordProviderTest.java new file mode 100644 index 00000000000..a828238584d --- /dev/null +++ b/common/src/test/java/io/druid/metadata/EnvironmentVariablePasswordProviderTest.java @@ -0,0 +1,42 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.druid.metadata; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class EnvironmentVariablePasswordProviderTest +{ + private static final ObjectMapper jsonMapper = new ObjectMapper(); + + @Test + public void testSerde() throws IOException + { + String providerString = "{\"type\": \"environment\", \"variable\" : \"test\"}"; + PasswordProvider provider = jsonMapper.readValue(providerString, PasswordProvider.class); + Assert.assertTrue(provider instanceof EnvironmentVariablePasswordProvider); + Assert.assertEquals("test", ((EnvironmentVariablePasswordProvider) provider).getVariable()); + PasswordProvider serde = jsonMapper.readValue(jsonMapper.writeValueAsString(provider), PasswordProvider.class); + Assert.assertEquals(provider, serde); + } +} diff --git a/docs/content/configuration/index.md b/docs/content/configuration/index.md index e0fa697ea3f..7e4c9c51f18 100644 --- a/docs/content/configuration/index.md +++ b/docs/content/configuration/index.md @@ -198,7 +198,7 @@ These properties specify the jdbc connection and other configuration around the |`druid.metadata.storage.type`|The type of metadata storage to use. Choose from "mysql", "postgresql", or "derby".|derby| |`druid.metadata.storage.connector.connectURI`|The jdbc uri for the database to connect to|none| |`druid.metadata.storage.connector.user`|The username to connect with.|none| -|`druid.metadata.storage.connector.password`|The password to connect with.|none| +|`druid.metadata.storage.connector.password`|The password provider or String password used to connect with.|none| |`druid.metadata.storage.connector.createTables`|If Druid requires a table and it doesn't exist, create it?|true| |`druid.metadata.storage.tables.base`|The base name for tables.|druid| |`druid.metadata.storage.tables.segments`|The table to use to look for segments.|druid_segments| @@ -210,6 +210,26 @@ These properties specify the jdbc connection and other configuration around the |`druid.metadata.storage.tables.supervisors`|Used by the indexing service to store supervisor configurations.|druid_supervisors| |`druid.metadata.storage.tables.audit`|The table to use for audit history of configuration changes e.g. Coordinator rules.|druid_audit| +#### Password Provider + +Environment variable password provider provides password by looking at specified environment variable. Use this in order to avoid specifying password in runtime.properties file. +e.g + +```json +{ + "type": "environment", + "variable": "METADATA_STORAGE_PASSWORD" +} +``` + +The values are described below. + +|Field|Type|Description|Required| +|-----|----|-----------|--------| +|`type`|String|password provider type|Yes: `environment`| +|`variable`|String|environment variable to read password from|Yes| + + ### Deep Storage The configurations concern how to push and pull [Segments](../design/segments.html) from deep storage.