Skip to content

Commit

Permalink
crypto plugin abstractions,encrypted repositories and metadata mgmt
Browse files Browse the repository at this point in the history
Signed-off-by: Vikas Bansal <[email protected]>
  • Loading branch information
vikasvb90 committed Jun 21, 2023
1 parent 68c1c86 commit 66d34f3
Show file tree
Hide file tree
Showing 22 changed files with 1,496 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,14 @@ public static void registerExceptions() {
V_2_7_0
)
);
registerExceptionHandle(
new OpenSearchExceptionHandle(
org.opensearch.crypto.CryptoClientMissingException.class,
org.opensearch.crypto.CryptoClientMissingException::new,
171,
V_3_0_0
)
);
registerExceptionHandle(
new OpenSearchExceptionHandle(
org.opensearch.cluster.block.IndexCreateBlockException.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.action.admin.cluster.crypto;

import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
import org.opensearch.common.io.stream.Writeable;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.xcontent.XContentType;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Map;

import static org.opensearch.action.ValidateActions.addValidationError;
import static org.opensearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
import static org.opensearch.common.settings.Settings.readSettingsFromStream;
import static org.opensearch.common.settings.Settings.writeSettingsToStream;

/**
* Crypto settings supplied during a put repository request
*
* @opensearch.internal
*/
public class CryptoSettings implements Writeable, ToXContentObject {

private String keyProviderName;
private String keyProviderType;
private Settings settings = EMPTY_SETTINGS;

public CryptoSettings(StreamInput in) throws IOException {
keyProviderName = in.readString();
keyProviderType = in.readString();
settings = readSettingsFromStream(in);
}

public CryptoSettings(String keyProviderName) {
this.keyProviderName = keyProviderName;
}

/**
* Validate settings supplied in put repository request.
* @return Exception in case validation fails.
*/
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
if (keyProviderName == null) {
validationException = addValidationError("key_provider_name is missing", validationException);
}
if (keyProviderType == null) {
validationException = addValidationError("key_provider_type is missing", validationException);
}
return validationException;
}

/**
* Returns key provider name
* @return keyProviderName
*/
public String getKeyProviderName() {
return keyProviderName;
}

/**
* Returns key provider type
* @return keyProviderType
*/
public String getKeyProviderType() {
return keyProviderType;
}

/**
* Returns crypto settings
* @return settings
*/
public Settings getSettings() {
return settings;
}

/**
* Constructs a new crypto settings with provided key provider name.
* @param keyProviderName Name of the key provider
*/
public CryptoSettings keyProviderName(String keyProviderName) {
this.keyProviderName = keyProviderName;
return this;
}

/**
* Constructs a new crypto settings with provided key provider type.
* @param keyProviderType Type of key provider to be used in encryption.
*/
public CryptoSettings keyProviderType(String keyProviderType) {
this.keyProviderType = keyProviderType;
return this;
}

/**
* Sets the encryption settings
*
* @param settings for encryption
* @return this request
*/
public CryptoSettings settings(Settings.Builder settings) {
this.settings = settings.build();
return this;
}

/**
* Sets the encryption settings.
*
* @param source encryption settings in json or yaml format
* @param xContentType the content type of the source
* @return this request
*/
public CryptoSettings settings(String source, XContentType xContentType) {
this.settings = Settings.builder().loadFromSource(source, xContentType).build();
return this;
}

/**
* Sets the encryption settings.
*
* @param source encryption settings
* @return this request
*/
public CryptoSettings settings(Map<String, Object> source) {
this.settings = Settings.builder().loadFromMap(source).build();
return this;
}

/**
* Parses crypto settings definition.
*
* @param cryptoDefinition crypto settings definition
*/
public CryptoSettings(Map<String, Object> cryptoDefinition) {
for (Map.Entry<String, Object> entry : cryptoDefinition.entrySet()) {
if (entry.getKey().equals("key_provider_name")) {
keyProviderName(entry.getValue().toString());
} else if (entry.getKey().equals("key_provider_type")) {
keyProviderType(entry.getValue().toString());
} else if (entry.getKey().equals("settings")) {
if (!(entry.getValue() instanceof Map)) {
throw new IllegalArgumentException("Malformed settings section in crypto settings, should include an inner object");
}
@SuppressWarnings("unchecked")
Map<String, Object> sub = (Map<String, Object>) entry.getValue();
settings(sub);
}
}
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(keyProviderName);
out.writeString(keyProviderType);
writeSettingsToStream(settings, out);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("key_provider_name", keyProviderName);
builder.field("key_provider_type", keyProviderType);

builder.startObject("settings");
settings.toXContent(builder, params);
builder.endObject();

builder.endObject();
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

/**
* Crypto client request and settings handlers.
*/
package org.opensearch.action.admin.cluster.crypto;
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@

package org.opensearch.action.admin.cluster.repositories.put;

import org.opensearch.Version;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.admin.cluster.crypto.CryptoSettings;
import org.opensearch.action.support.master.AcknowledgedRequest;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
Expand All @@ -48,6 +50,7 @@
import static org.opensearch.common.settings.Settings.readSettingsFromStream;
import static org.opensearch.common.settings.Settings.writeSettingsToStream;
import static org.opensearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
import static org.opensearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;

/**
* Register repository request.
Expand All @@ -67,12 +70,22 @@ public class PutRepositoryRequest extends AcknowledgedRequest<PutRepositoryReque

private Settings settings = EMPTY_SETTINGS;

private Boolean encrypted;
private CryptoSettings cryptoSettings;

public PutRepositoryRequest(StreamInput in) throws IOException {
super(in);
name = in.readString();
type = in.readString();
settings = readSettingsFromStream(in);
verify = in.readBoolean();

if (in.getVersion().onOrAfter(Version.V_3_0_0)) {
encrypted = in.readOptionalBoolean();
if (Boolean.TRUE.equals(encrypted)) {
cryptoSettings = new CryptoSettings(in);
}
}
}

public PutRepositoryRequest() {}
Expand All @@ -93,6 +106,13 @@ public ActionRequestValidationException validate() {
if (type == null) {
validationException = addValidationError("type is missing", validationException);
}
if (Boolean.TRUE.equals(encrypted)) {
if (cryptoSettings == null) {
validationException = addValidationError("crypto_settings is missing", validationException);
} else {
validationException = cryptoSettings.validate();
}
}
return validationException;
}

Expand Down Expand Up @@ -207,6 +227,41 @@ public boolean verify() {
return this.verify;
}

/**
* Sets whether repository data should be encrypted and stored.
*/
public PutRepositoryRequest encrypted(Boolean encrypted) {
this.encrypted = encrypted;
return this;
}

/**
* Returns true if repository should be encrypted
*/
public Boolean encrypted() {
return encrypted;
}

/**
* Sets the repository crypto settings
*
* @param cryptoSettings repository crypto settings
* @return this request
*/
public PutRepositoryRequest cryptoSettings(CryptoSettings cryptoSettings) {
this.cryptoSettings = cryptoSettings;
return this;
}

/**
* Returns repository encryption settings
*
* @return repository encryption settings
*/
public CryptoSettings cryptoSettings() {
return cryptoSettings;
}

/**
* Parses repository definition.
*
Expand All @@ -224,6 +279,16 @@ public PutRepositoryRequest source(Map<String, Object> repositoryDefinition) {
@SuppressWarnings("unchecked")
Map<String, Object> sub = (Map<String, Object>) entry.getValue();
settings(sub);
} else if (name.equals("encrypted")) {
encrypted(nodeBooleanValue(entry.getValue(), "encrypted"));
} else if (name.equals("crypto_settings")) {
if (!(entry.getValue() instanceof Map)) {
throw new IllegalArgumentException("Malformed encryption_settings section, should include an inner object");
}
@SuppressWarnings("unchecked")
Map<String, Object> sub = (Map<String, Object>) entry.getValue();
CryptoSettings cryptoSettings = new CryptoSettings(sub);
cryptoSettings(cryptoSettings);
}
}
return this;
Expand All @@ -236,6 +301,12 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(type);
writeSettingsToStream(settings, out);
out.writeBoolean(verify);
if (out.getVersion().onOrAfter(Version.V_3_0_0)) {
out.writeOptionalBoolean(encrypted);
if (Boolean.TRUE.equals(encrypted)) {
cryptoSettings.writeTo(out);
}
}
}

@Override
Expand All @@ -249,6 +320,16 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.endObject();

builder.field("verify", verify);

if (null != encrypted) {
builder.field("encrypted", encrypted);
if (encrypted == true) {
builder.startObject("crypto_settings");
cryptoSettings.toXContent(builder, params);
builder.endObject();
}
}

builder.endObject();
return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

package org.opensearch.action.admin.cluster.repositories.put;

import org.opensearch.action.admin.cluster.crypto.CryptoSettings;
import org.opensearch.action.support.master.AcknowledgedRequestBuilder;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.client.OpenSearchClient;
Expand Down Expand Up @@ -141,4 +142,26 @@ public PutRepositoryRequestBuilder setVerify(boolean verify) {
request.verify(verify);
return this;
}

/**
* Sets whether repository data should be encrypted and stored.
*
* @param encrypted true if repository data should be encrypted and stored, false otherwise
* @return this builder
*/
public PutRepositoryRequestBuilder setEncrypted(Boolean encrypted) {
request.encrypted(encrypted);
return this;
}

/**
* Sets the repository encryption settings
*
* @param cryptoSettings repository crypto settings builder
* @return this builder
*/
public PutRepositoryRequestBuilder setEncryptionSettings(CryptoSettings cryptoSettings) {
request.cryptoSettings(cryptoSettings);
return this;
}
}
Loading

0 comments on commit 66d34f3

Please sign in to comment.