feat: Add functionality to opt out plugin from airgap instance (#22098)

## Description

As a part of supporting airgap instances we want to restrict the plugins
which have any public dependency. This PR introduces a config setting
for plugins to opt out of airgap.
Also as a part of this exercise we are also adding a setting for CS
dependency which can be utilised in future if our customers wants to opt
out of CS dependent plugins.
Corresponding EE PR:
https://github.com/appsmithorg/appsmith-ee/pull/1258

> TL;DR: Provide a way for plugins supported in Appsmith to opt-out of
airgap instances

Fixes https://github.com/appsmithorg/appsmith/issues/21499

## Type of change

- New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

- Manual

## Checklist:
### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes

### QA activity:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
This commit is contained in:
Abhijeet 2023-04-06 23:15:03 +05:30 committed by GitHub
parent 6ac99037b0
commit f66410ebcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,14 @@
package com.appsmith.external.constants;
public interface PluginConstants {
interface PackageName {
String SAAS_PLUGIN = "saas-plugin";
String RAPID_API_PLUGIN = "rapidapi-plugin";
String FIRESTORE_PLUGIN = "firestore-plugin";
String REDSHIFT_PLUGIN = "redshift-plugin";
String DYNAMO_PLUGIN = "dynamo-plugin";
String AMAZON_S3_PLUGIN = "amazons3-plugin";
String GOOGLE_SHEETS_PLUGIN = "google-sheets-plugin";
}
}

View File

@ -107,4 +107,14 @@ public class Plugin extends BaseDomain {
@JsonView(Views.Public.class) @JsonView(Views.Public.class)
Map<String, String> templates; Map<String, String> templates;
// Field to distinguish if the plugin is supported in air-gap instance, by default all the plugins will be supported.
// One can opt out by adding this field in DB object. Generally SaaS plugins and DB which can't be self-hosted can
// be a candidate for opting out of air-gap
@JsonView(Views.Internal.class)
boolean isSupportedForAirGap = true;
// Config to set if the plugin has any dependency on cloud-services
@JsonView(Views.Internal.class)
Boolean isDependentOnCS;
} }

View File

@ -0,0 +1,62 @@
package com.appsmith.server.migrations.db.ce;
import com.appsmith.external.models.PluginType;
import com.appsmith.server.domains.Plugin;
import io.mongock.api.annotations.ChangeUnit;
import io.mongock.api.annotations.Execution;
import io.mongock.api.annotations.RollbackExecution;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.util.List;
import java.util.Set;
import static com.appsmith.external.constants.PluginConstants.PackageName.AMAZON_S3_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.DYNAMO_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.FIRESTORE_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.GOOGLE_SHEETS_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.RAPID_API_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.REDSHIFT_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.SAAS_PLUGIN;
@ChangeUnit(order = "005", id="opt-out-unsupported-plugins-airgap-instance", author = " ")
public class Migration005OptOutUnsupportedPluginsForAirGap {
private final MongoTemplate mongoTemplate;
public Migration005OptOutUnsupportedPluginsForAirGap(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
@RollbackExecution
public void rollBackExecution() {
}
@Execution
public void optOutUnsupportedPluginsForAirGapInstance() {
// By default, all the plugins will be supported in air-gap instance.
// One can opt out the support for plugin by adding `isSupportedForAirGap:false` in DB object.
// Generally SaaS plugins and DBs which can't be self-hosted can be a candidate for opting out of air-gap as
// these are dependent on external internet
final Set<String> unsupportedPluginPackageNameInAirgap = Set.of(
SAAS_PLUGIN, RAPID_API_PLUGIN, FIRESTORE_PLUGIN, REDSHIFT_PLUGIN, DYNAMO_PLUGIN,
AMAZON_S3_PLUGIN, GOOGLE_SHEETS_PLUGIN
);
final Set<PluginType> cloudServicesDependentPluginTypes = Set.of(PluginType.SAAS, PluginType.REMOTE);
List<Plugin> plugins = mongoTemplate.findAll(Plugin.class);
for (Plugin plugin : plugins) {
if (unsupportedPluginPackageNameInAirgap.contains(plugin.getPackageName())
|| cloudServicesDependentPluginTypes.contains(plugin.getType())) {
if (unsupportedPluginPackageNameInAirgap.contains(plugin.getPackageName())) {
plugin.setSupportedForAirGap(false);
}
if (cloudServicesDependentPluginTypes.contains(plugin.getType())) {
plugin.setIsDependentOnCS(true);
}
mongoTemplate.save(plugin);
}
}
}
}

View File

@ -178,6 +178,15 @@ The `BasePlugin` & `PluginExecutor` classes define the basic operations of plugi
plugin.setIconLocation("https://your-plugin-icon-location.png"); plugin.setIconLocation("https://your-plugin-icon-location.png");
plugin.setDocumentationLink("https://link-to-plugin-documentation.html"); plugin.setDocumentationLink("https://link-to-plugin-documentation.html");
plugin.setDefaultInstall(true); plugin.setDefaultInstall(true);
// Field to distinguish if the plugin is supported in air-gap instance, by default all the plugins will be
// supported. One can opt out by adding this field in DB object. Generally SaaS plugins and DB which can't be
// self-hosted can be a candidate for opting out of air-gap
plugin.setSupportedForAirGap(false);
// Config to set if the plugin has any dependency on cloud-services
plugin.setIsDependentOnCS(true);
try { try {
mongoTemplate.insert(plugin); mongoTemplate.insert(plugin);
} catch (DuplicateKeyException e) { } catch (DuplicateKeyException e) {