fix: S3 plugin: provide support for MinIO (#11766)
* update option label * add minIO as a separate datasource option add datasource connection changes to support minIO without SSL and when using CA signed certificates * fix cypress tests
This commit is contained in:
parent
8eea57358c
commit
40f4e3c755
|
|
@ -120,7 +120,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications",
|
|||
"File content is not base64 encoded.",
|
||||
);
|
||||
});
|
||||
cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary");
|
||||
cy.validateNSelectDropdown("File Data Type", "Base64", "Text");
|
||||
|
||||
cy.onlyQueryRun();
|
||||
cy.wait("@postExecute").then(({ response }) => {
|
||||
|
|
@ -249,7 +249,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications",
|
|||
cy.typeValueNValidate("AutoFile", "File Path");
|
||||
|
||||
//Commenting below since below dropdown is removed from Read
|
||||
//cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary");
|
||||
//cy.validateNSelectDropdown("File Data Type", "Base64", "Text");
|
||||
|
||||
cy.onlyQueryRun();
|
||||
cy.wait("@postExecute").then(({ response }) => {
|
||||
|
|
@ -343,7 +343,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications",
|
|||
);
|
||||
cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name");
|
||||
cy.typeValueNValidate("CRUDNewPageFile", "File Path");
|
||||
cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary");
|
||||
cy.validateNSelectDropdown("File Data Type", "Base64", "Text");
|
||||
cy.typeValueNValidate(
|
||||
'{"data": "Hi, this is Automation script adding file for S3 CRUD New Page validation!"}',
|
||||
"Content",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException
|
|||
import com.appsmith.external.models.Condition;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.models.Endpoint;
|
||||
import com.appsmith.external.models.Property;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
|
@ -288,4 +289,22 @@ public class PluginUtils {
|
|||
public static List<String> parseList(String arrayString) throws IOException {
|
||||
return objectMapper.readValue(arrayString, ArrayList.class);
|
||||
}
|
||||
|
||||
public static <T> T getValueSafelyFromPropertyList(List<Property> properties, int index, Class<T> type,
|
||||
T defaultValue) {
|
||||
if (CollectionUtils.isEmpty(properties) || index > properties.size() - 1 || properties.get(index) == null
|
||||
|| properties.get(index).getValue() == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return (T) properties.get(index).getValue();
|
||||
}
|
||||
|
||||
public static <T> T getValueSafelyFromPropertyList(List<Property> properties, int index, Class<T> type) {
|
||||
return getValueSafelyFromPropertyList(properties, index, type, null);
|
||||
}
|
||||
|
||||
public static Object getValueSafelyFromPropertyList(List<Property> properties, int index) {
|
||||
return getValueSafelyFromPropertyList(properties, index, Object.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.external.utils;
|
||||
|
||||
import com.amazonaws.ClientConfiguration;
|
||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||
|
|
@ -17,6 +19,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import static com.amazonaws.regions.Regions.DEFAULT_REGION;
|
||||
import static com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError.PLUGIN_ERROR;
|
||||
import static com.appsmith.external.helpers.PluginUtils.getValueSafelyFromPropertyList;
|
||||
import static com.external.plugins.AmazonS3Plugin.CUSTOM_ENDPOINT_INDEX;
|
||||
import static com.external.plugins.AmazonS3Plugin.CUSTOM_ENDPOINT_REGION_PROPERTY_INDEX;
|
||||
import static com.external.plugins.AmazonS3Plugin.S3_SERVICE_PROVIDER_PROPERTY_INDEX;
|
||||
|
|
@ -59,6 +62,7 @@ public class DatasourceUtils {
|
|||
WASABI ("wasabi"),
|
||||
DIGITAL_OCEAN_SPACES ("digital-ocean-spaces"),
|
||||
DREAM_OBJECTS ("dream-objects"),
|
||||
MINIO ("minio"),
|
||||
OTHER ("other");
|
||||
|
||||
private String name;
|
||||
|
|
@ -183,6 +187,31 @@ public class DatasourceUtils {
|
|||
region = getRegionFromEndpointPattern(endpoint, DREAM_OBJECTS_URL_ENDPOINT_PATTERN,
|
||||
DREAM_OBJECTS_REGION_GROUP_INDEX);
|
||||
|
||||
break;
|
||||
case MINIO:
|
||||
region = getUserProvidedRegion(properties);
|
||||
if (StringUtils.isBlank(region)) {
|
||||
/**
|
||||
* Set a default region in case user has not provided a region.
|
||||
* Minio server can be configured to work both ways - with or without region attribute. Hence,
|
||||
* it is upto the user to know whether the Minio server they want to connect to has been
|
||||
* configured with a region or not.
|
||||
* As per my experimentation, in case the Minio server has not been configured with a region
|
||||
* attribute, then any placeholder value will work. However, I am going with US_EAST_1 here
|
||||
* since this the value that Minio documentation uses to show example applications.
|
||||
* Ref: https://docs.min.io/docs/how-to-use-aws-sdk-for-java-with-minio-server.html
|
||||
*/
|
||||
region = Regions.US_EAST_1.getName();
|
||||
}
|
||||
|
||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||
clientConfiguration.setSignerOverride("AWSS3V4SignerType");
|
||||
|
||||
/* Ref: https://docs.min.io/docs/how-to-use-aws-sdk-for-java-with-minio-server.html */
|
||||
s3ClientBuilder = s3ClientBuilder
|
||||
.withPathStyleAccessEnabled(true)
|
||||
.withClientConfiguration(clientConfiguration);
|
||||
|
||||
break;
|
||||
default:
|
||||
region = (String) properties.get(CUSTOM_ENDPOINT_REGION_PROPERTY_INDEX).getValue();
|
||||
|
|
@ -195,6 +224,10 @@ public class DatasourceUtils {
|
|||
return s3ClientBuilder;
|
||||
}
|
||||
|
||||
private static String getUserProvidedRegion(List<Property> properties) {
|
||||
return getValueSafelyFromPropertyList(properties, CUSTOM_ENDPOINT_REGION_PROPERTY_INDEX, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if the S3 endpoint URL has correct format and extracts region information from it.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
"value": "YES"
|
||||
},
|
||||
{
|
||||
"label": "Text / Binary",
|
||||
"label": "Text",
|
||||
"value": "NO"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@
|
|||
"label": "DreamObjects",
|
||||
"value": "dream-objects"
|
||||
},
|
||||
{
|
||||
"label": "MinIO",
|
||||
"value": "minio"
|
||||
},
|
||||
{
|
||||
"label": "Other",
|
||||
"value": "other"
|
||||
|
|
@ -48,6 +52,7 @@
|
|||
"label": "Access Key",
|
||||
"configProperty": "datasourceConfiguration.authentication.username",
|
||||
"controlType": "INPUT_TEXT",
|
||||
"isRequired": true,
|
||||
"initialValue": ""
|
||||
},
|
||||
{
|
||||
|
|
@ -56,14 +61,16 @@
|
|||
"controlType": "INPUT_TEXT",
|
||||
"dataType": "PASSWORD",
|
||||
"initialValue": "",
|
||||
"isRequired": true,
|
||||
"encrypted": true
|
||||
},
|
||||
{
|
||||
"label": "Endpoint URL",
|
||||
"label": "Endpoint URL (with or without protocol and port no)",
|
||||
"configProperty": "datasourceConfiguration.endpoints[0].host",
|
||||
"controlType": "INPUT_TEXT",
|
||||
"initialValue": "",
|
||||
"placeholderText": "user-storage.de-fra1.upcloudobjects.com",
|
||||
"isRequired": true,
|
||||
"placeholderText": "https://user-storage.de-fra1.upcloudobjects.com",
|
||||
"hidden": {
|
||||
"path": "datasourceConfiguration.properties[1].value",
|
||||
"comparison": "EQUALS",
|
||||
|
|
@ -84,9 +91,19 @@
|
|||
"initialValue": "",
|
||||
"placeholderText": "de-fra1",
|
||||
"hidden": {
|
||||
"path": "datasourceConfiguration.properties[1].value",
|
||||
"comparison": "NOT_EQUALS",
|
||||
"value": "other"
|
||||
"conditionType": "AND",
|
||||
"conditions": [
|
||||
{
|
||||
"path": "datasourceConfiguration.properties[1].value",
|
||||
"comparison": "NOT_EQUALS",
|
||||
"value": "other"
|
||||
},
|
||||
{
|
||||
"path": "datasourceConfiguration.properties[1].value",
|
||||
"comparison": "NOT_EQUALS",
|
||||
"value": "minio"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user