Merge branch 'endgame-202407' into endgame-202407.next
This commit is contained in:
Коммит
b5e00fd6a6
|
@ -27,7 +27,7 @@
|
|||
<parent>
|
||||
<groupId>com.microsoft.azuretools</groupId>
|
||||
<artifactId>utils</artifactId>
|
||||
<version>3.91.0-SNAPSHOT</version>
|
||||
<version>3.91.0</version>
|
||||
</parent>
|
||||
<groupId>com.microsoft.azuretools</groupId>
|
||||
<artifactId>com.microsoft.azuretools.sdk.lib</artifactId>
|
||||
|
@ -39,9 +39,9 @@
|
|||
</organization>
|
||||
|
||||
<properties>
|
||||
<azuretool.version>3.91.0-SNAPSHOT</azuretool.version>
|
||||
<azuretool.version>3.91.0</azuretool.version>
|
||||
<azuretool.sdk.version>3.32.0.qualifier</azuretool.sdk.version>
|
||||
<azure.toolkit-lib.version>0.47.0-SNAPSHOT</azure.toolkit-lib.version>
|
||||
<azure.toolkit-lib.version>0.47.0</azure.toolkit-lib.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
|
@ -43,4 +43,4 @@ Export-Package: com.microsoft.azuretools.appservice,
|
|||
com.microsoft.azuretools.appservice.handlers,
|
||||
com.microsoft.azuretools.appservice.ui
|
||||
Bundle-ClassPath: .,
|
||||
target/lib/azure-toolkit-ide-appservice-lib-0.47.0-SNAPSHOT.jar
|
||||
target/lib/azure-toolkit-ide-appservice-lib-0.47.0.jar
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<dependency>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-toolkit-ide-appservice-lib</artifactId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
|
|
|
@ -23,7 +23,7 @@ Require-Bundle: org.eclipse.ui,
|
|||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .,
|
||||
target/lib/azure-toolkit-ide-springcloud-lib-0.47.0-SNAPSHOT.jar
|
||||
target/lib/azure-toolkit-ide-springcloud-lib-0.47.0.jar
|
||||
Import-Package: com.microsoft.azuretools.core.actions,
|
||||
org.eclipse.core.expressions,
|
||||
org.eclipse.jface.text.hyperlink,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<dependency>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-toolkit-ide-springcloud-lib</artifactId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
<option value="$PROJECT_DIR$/azure-intellij-plugin-hdinsight-lib" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-integration-services" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-keyvault" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-keyvault-java" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-lib" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-lib-java" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-monitor" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-redis" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-redis-java" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-samples" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-service-explorer" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-servicebus" />
|
||||
|
@ -41,6 +43,7 @@
|
|||
<option value="$PROJECT_DIR$/azure-intellij-plugin-springcloud" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-sqlserverbigdata" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-storage" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-storage-java" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-synapse" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-plugin-vm" />
|
||||
<option value="$PROJECT_DIR$/azure-intellij-resource-connector-aad" />
|
||||
|
|
|
@ -20,6 +20,7 @@ dependencies {
|
|||
implementation(project(":azure-intellij-plugin-containerapps"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-containerapps", configuration: "instrumentedJar")
|
||||
implementation("com.github.docker-java:docker-java:3.3.0")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-appservice-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-appservice-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-containerapps-lib")
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.DotEnvBeforeRunTaskProvider;
|
||||
import com.microsoft.azure.toolkit.intellij.legacy.common.AzureRunProfileState;
|
||||
import com.microsoft.azure.toolkit.intellij.legacy.function.runner.core.FunctionUtils;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.BaseStorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.config.FunctionAppConfig;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.function.FunctionApp;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.function.FunctionAppBase;
|
||||
|
@ -99,7 +99,7 @@ public class FunctionDeploymentState extends AzureRunProfileState<FunctionAppBas
|
|||
final Map<String, String> appSettings = functionDeployConfiguration.getConfig().appSettings();
|
||||
loadDotEnvBeforeRunTask.loadEnv().stream()
|
||||
.filter(pair -> !(StringUtils.equalsIgnoreCase(pair.getKey(), "AzureWebJobsStorage") &&
|
||||
StringUtils.equalsIgnoreCase(pair.getValue(), StorageAccountResourceDefinition.LOCAL_STORAGE_CONNECTION_STRING))) // workaround to remove local connections
|
||||
StringUtils.equalsIgnoreCase(pair.getValue(), BaseStorageAccountResourceDefinition.LOCAL_STORAGE_CONNECTION_STRING))) // workaround to remove local connections
|
||||
.forEach(env -> appSettings.put(env.getKey(), env.getValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContri
|
|||
import com.microsoft.azure.toolkit.intellij.common.AzureArtifact;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureArtifactManager;
|
||||
import com.microsoft.azure.toolkit.intellij.common.RunProcessHandler;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.*;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.DotEnvBeforeRunTaskProvider;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
||||
import com.microsoft.azure.toolkit.intellij.legacy.common.AzureRunProfileState;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.config.AppServiceConfig;
|
||||
|
@ -24,6 +26,7 @@ import com.microsoft.azure.toolkit.lib.appservice.model.DeployType;
|
|||
import com.microsoft.azure.toolkit.lib.appservice.model.WebAppArtifact;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.task.CreateOrUpdateWebAppTask;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.task.DeployWebAppTask;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.webapp.WebApp;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.webapp.WebAppBase;
|
||||
import com.microsoft.azure.toolkit.lib.appservice.webapp.WebAppDeploymentSlot;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.Action;
|
||||
|
@ -36,10 +39,14 @@ import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
|||
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
|
||||
import com.microsoft.azure.toolkit.lib.common.operation.OperationContext;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import com.microsoft.azure.toolkit.lib.identities.ManagedIdentitySupport;
|
||||
import com.microsoft.azure.toolkit.lib.identities.model.IdentityConfiguration;
|
||||
import com.microsoft.azuretools.telemetry.TelemetryConstants;
|
||||
import com.microsoft.azuretools.telemetrywrapper.Operation;
|
||||
import com.microsoft.azuretools.telemetrywrapper.TelemetryManager;
|
||||
import com.microsoft.azuretools.utils.WebAppUtils;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.compress.utils.FileNameUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
@ -54,8 +61,10 @@ import java.io.FileNotFoundException;
|
|||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.microsoft.azure.toolkit.intellij.common.AzureBundle.message;
|
||||
import static com.microsoft.azure.toolkit.intellij.connector.IManagedIdentitySupported.*;
|
||||
|
||||
public class WebAppRunState extends AzureRunProfileState<WebAppBase<?, ?, ?>> {
|
||||
private static final String LIBS_ROOT = "/home/site/wwwroot/libs/";
|
||||
|
@ -90,27 +99,79 @@ public class WebAppRunState extends AzureRunProfileState<WebAppBase<?, ?, ?>> {
|
|||
if (!artifact.exists()) {
|
||||
throw new FileNotFoundException(message("webapp.deploy.error.noTargetFile", artifact.getAbsolutePath()));
|
||||
}
|
||||
final WebAppBase<?, ?, ?> deployTarget = getOrCreateDeployTarget();
|
||||
final AzureModule module = Optional.ofNullable(this.webAppConfiguration.getModule()).map(AzureModule::from)
|
||||
.or(() -> Optional.ofNullable(getTargetPath())
|
||||
.map(f -> VfsUtil.findFile(Path.of(f), true))
|
||||
.map(f -> AzureModule.from(f, this.project))).orElse(null);
|
||||
final WebAppBase<?, ?, ?> deployTarget = getOrCreateDeployTarget(module);
|
||||
// todo: remove workaround after fix reset issue in toolkit lib
|
||||
if (deployTarget instanceof AzResource.Draft<?, ?> draft) {
|
||||
draft.reset();
|
||||
}
|
||||
if (deployTarget instanceof WebApp app) {
|
||||
Optional.ofNullable(module).map(AzureModule::getDefaultProfile).ifPresent(p -> updateResourceConnectionWithIdentity(app, p));
|
||||
Optional.ofNullable(module).map(AzureModule::getDefaultProfile).ifPresent(p -> validatePermissionForIdentityConnections(app, p));
|
||||
}
|
||||
webAppConfiguration.setWebApp(deployTarget);
|
||||
deployArtifactsToWebApp(deployTarget, artifact, webAppSettingModel.isDeployToRoot());
|
||||
return deployTarget;
|
||||
}
|
||||
|
||||
public static <T extends ManagedIdentitySupport> void validatePermissionForIdentityConnections(T target, Profile profile) {
|
||||
final IdentityConfiguration configuration = target.getIdentityConfiguration();
|
||||
final List<Connection<?, ?>> list = profile.getConnections().stream().filter(Connection::isManagedIdentityConnection).toList();
|
||||
list.forEach(con -> {
|
||||
final Resource<?> resource = con.getResource();
|
||||
final IManagedIdentitySupported<?> definition = (IManagedIdentitySupported<?>) resource.getDefinition();
|
||||
// todo: replace with real permission check
|
||||
if (MapUtils.isEmpty(definition.getBuiltInRoles())) {
|
||||
return;
|
||||
}
|
||||
final AbstractAzResource<?,?,?> data = (AbstractAzResource<?,?,?>) resource.getData();
|
||||
final String identity = con.getAuthenticationType() == AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY ?
|
||||
configuration.getPrincipalId() : Objects.requireNonNull(con.getUserAssignedManagedIdentity()).getData().getPrincipalId();
|
||||
final String identityName = con.getAuthenticationType() == AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY ?
|
||||
target instanceof AzResource ? ((AzResource)target).getName() : target.toString() :
|
||||
Objects.requireNonNull(con.getUserAssignedManagedIdentity()).getData().getName();
|
||||
if (resource instanceof AzureServiceResource<?> serviceResource && !checkPermission(serviceResource, identity)) {
|
||||
if (!IManagedIdentitySupported.grantPermission(serviceResource, identity)) {
|
||||
final String message = String.format("The managed identity %s (%s) doesn't have enough permission to access resource %s.", identity, identityName, resource.getName());
|
||||
final Action<?> openIdentityConfigurationAction = getOpenIdentityConfigurationAction(serviceResource);
|
||||
final Action<?> grantPermissionAction = getGrantPermissionAction(serviceResource, identity);
|
||||
AzureMessager.getMessager().warning(message, openIdentityConfigurationAction, grantPermissionAction);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T extends ManagedIdentitySupport> void updateResourceConnectionWithIdentity(T target, Profile profile) {
|
||||
final IdentityConfiguration current = target.getIdentityConfiguration();
|
||||
final boolean currentSystemIdentityEnabled = Optional.ofNullable(current).map(IdentityConfiguration::isEnableSystemAssignedManagedIdentity).orElse(false);
|
||||
final List<Identity> currentIdentities = Optional.ofNullable(current).map(IdentityConfiguration::getUserAssignedManagedIdentities).orElse(Collections.emptyList());
|
||||
final List<Connection<?, ?>> list = profile.getConnections().stream().filter(Connection::isManagedIdentityConnection).toList();
|
||||
final boolean shouldEnableSystemManagedIdentity = list.stream().anyMatch(c -> c.getAuthenticationType() == AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY);
|
||||
final List<Identity> connectionIdentities = list.stream()
|
||||
.map(Connection::getUserAssignedManagedIdentity).filter(Objects::nonNull).map(Resource::getData).filter(Objects::nonNull).toList();
|
||||
if (shouldEnableSystemManagedIdentity == currentSystemIdentityEnabled && CollectionUtils.containsAll(currentIdentities, connectionIdentities)) {
|
||||
return;
|
||||
}
|
||||
final List<Identity> identities = Stream.concat(currentIdentities.stream(), connectionIdentities.stream()).toList();
|
||||
final IdentityConfiguration updatedConfiguration = IdentityConfiguration.builder()
|
||||
.enableSystemAssignedManagedIdentity(shouldEnableSystemManagedIdentity || currentSystemIdentityEnabled)
|
||||
.userAssignedManagedIdentities(identities)
|
||||
.build();
|
||||
if (!Objects.equals(updatedConfiguration, current)) {
|
||||
target.updateIdentityConfiguration(updatedConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebAppBase<?, ?, ?> getOrCreateDeployTarget() {
|
||||
private WebAppBase<?, ?, ?> getOrCreateDeployTarget(@Nullable final AzureModule module) {
|
||||
final AppServiceConfig appServiceConfig = webAppConfiguration.getAppServiceConfig();
|
||||
applyResourceConnections(webAppConfiguration, appServiceConfig);
|
||||
cleanupRemovedAppSettings(appServiceConfig);
|
||||
final WebAppBase<?, ?, ?> result = new CreateOrUpdateWebAppTask(appServiceConfig).execute();
|
||||
final AzureTaskManager tm = AzureTaskManager.getInstance();
|
||||
final AzureModule module = Optional.ofNullable(this.webAppConfiguration.getModule()).map(AzureModule::from)
|
||||
.or(() -> Optional.ofNullable(getTargetPath())
|
||||
.map(f -> VfsUtil.findFile(Path.of(f), true))
|
||||
.map(f -> AzureModule.from(f, this.project))).orElse(null);
|
||||
if (Objects.nonNull(module)) {
|
||||
final AbstractAzResource<?, ?, ?> target = result instanceof WebAppDeploymentSlot ? result.getParent() : result;
|
||||
tm.runOnPooledThread(() -> tm.runLater(() -> tm.write(() -> module.initializeWithDefaultProfileIfNot().addApp(target).save())));
|
||||
|
|
|
@ -42,8 +42,8 @@ allprojects {
|
|||
}
|
||||
|
||||
ext {
|
||||
azureToolkitLibsVersion = "0.47.0-SNAPSHOT"
|
||||
azureToolkitIdeLibsVersion = "0.47.0-SNAPSHOT"
|
||||
azureToolkitLibsVersion = "0.47.0"
|
||||
azureToolkitIdeLibsVersion = "0.47.0"
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pluginVersion=3.91.0-SNAPSHOT
|
||||
pluginVersion=3.91.0
|
||||
intellijDisplayVersion=2024.2
|
||||
intellij_version=IU-242-EAP-SNAPSHOT
|
||||
scala_plugin=org.intellij.scala:2024.2.5
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<id>com.microsoft.tooling.msservices.intellij.azure</id>
|
||||
<name>Azure Toolkit</name>
|
||||
<version>3.91.0-SNAPSHOT</version>
|
||||
<version>3.91.0</version>
|
||||
<vendor email="java@microsoft.com" url="http://www.microsoft.com">Microsoft</vendor>
|
||||
|
||||
<description>
|
||||
|
|
|
@ -16,6 +16,8 @@ dependencies {
|
|||
implementation("com.microsoft.azure:azure-toolkit-cosmos-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-cosmos-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
|
||||
intellijPlatform {
|
||||
intellijIdeaUltimate(properties("platformVersion").get())
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
|
|
|
@ -41,6 +41,9 @@ public class CosmosDatabaseResourcePanel<T extends ICosmosDatabase, E extends Co
|
|||
this.cbDatabase.setRequired(true);
|
||||
this.cbSubscription.addItemListener(this::onSubscriptionChanged);
|
||||
this.cbAccount.addItemListener(this::onAccountChanged);
|
||||
|
||||
this.cbDatabase.addValueChangedListener(ignore -> Optional.ofNullable(getValue()).ifPresent(this::fireValueChangedEvent));
|
||||
|
||||
}
|
||||
|
||||
private void onSubscriptionChanged(ItemEvent e) {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package com.microsoft.azure.toolkit.intellij.cosmos.connection;
|
||||
|
||||
import com.azure.resourcemanager.authorization.models.BuiltInRole;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AuthenticationType;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.function.FunctionSupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringManagedIdentitySupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringSupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.Subscription;
|
||||
|
@ -18,16 +21,13 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SqlCosmosDBAccountResourceDefinition extends AzureServiceResource.Definition<SqlDatabase>
|
||||
implements SpringSupported<SqlDatabase>, FunctionSupported<SqlDatabase> {
|
||||
implements SpringSupported<SqlDatabase>, FunctionSupported<SqlDatabase>, SpringManagedIdentitySupported<SqlDatabase> {
|
||||
public static final SqlCosmosDBAccountResourceDefinition INSTANCE = new SqlCosmosDBAccountResourceDefinition();
|
||||
|
||||
public SqlCosmosDBAccountResourceDefinition() {
|
||||
|
@ -96,4 +96,43 @@ public class SqlCosmosDBAccountResourceDefinition extends AzureServiceResource.D
|
|||
public String getResourceConnectionString(@Nonnull SqlDatabase resource) {
|
||||
return resource.getModule().getParent().getCosmosDBAccountPrimaryConnectionString().getConnectionString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initIdentityEnv(Connection<SqlDatabase, ?> data, Project project) {
|
||||
final SqlDatabase database = data.getResource().getData();
|
||||
final CosmosDBAccount account = database.getParent();
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
env.put(String.format("%s_ENDPOINT", Connection.ENV_PREFIX), account.getDocumentEndpoint());
|
||||
env.put(String.format("%s_DATABASE", Connection.ENV_PREFIX), database.getName());
|
||||
if (data.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
Optional.ofNullable(data.getUserAssignedManagedIdentity()).map(Resource::getData)
|
||||
.ifPresent(identity -> env.put(String.format("%s_CLIENT_ID", Connection.ENV_PREFIX), identity.getClientId()));
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredPermissions() {
|
||||
return List.of("Microsoft.DocumentDB/databaseAccounts/readMetadata",
|
||||
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
|
||||
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<String, BuiltInRole> getBuiltInRoles() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getSpringPropertiesForManagedIdentity(String key, Connection<?, ?> connection) {
|
||||
final List<Pair<String, String>> properties = new ArrayList<>();
|
||||
properties.add(Pair.of("spring.cloud.azure.cosmos.endpoint", String.format("${%s_ENDPOINT}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.cloud.azure.cosmos.database", String.format("${%s_DATABASE}", Connection.ENV_PREFIX)));
|
||||
// properties.add(Pair.of("spring.cloud.azure.cosmos.credential.managed-identity-enabled", String.valueOf(true)));
|
||||
if (connection.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
properties.add(Pair.of("spring.cloud.azure.cosmos.credential.client-id", String.format("${%s_CLIENT_ID}", Connection.ENV_PREFIX)));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
dependencies {
|
||||
implementation(project(":azure-intellij-plugin-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-plugin-keyvault"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-keyvault", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-keyvault-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-keyvault-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
bundledPlugin("com.intellij.java")
|
||||
bundledPlugin("org.jetbrains.plugins.yaml")
|
||||
bundledPlugin("com.intellij.properties")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.keyvault;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.microsoft.azure.toolkit.ide.common.IActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.keyvault.connection.KeyVaultResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.KeyVault;
|
||||
|
||||
public class IntellijJavaKeyVaultActionsContributor implements IActionsContributor {
|
||||
@Override
|
||||
public void registerHandlers(AzureActionManager am) {
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof KeyVault,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((KeyVault) r), KeyVaultResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -5,46 +5,34 @@
|
|||
|
||||
package com.microsoft.azure.toolkit.intellij.keyvault.connection;
|
||||
|
||||
import com.azure.resourcemanager.authorization.models.BuiltInRole;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AuthenticationType;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringManagedIdentitySupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringSupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.auth.AzureCloud;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.AzureKeyVault;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.KeyVault;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Getter
|
||||
public class KeyVaultResourceDefinition extends AzureServiceResource.Definition<KeyVault> implements SpringSupported<KeyVault> {
|
||||
public class KeyVaultResourceDefinition extends BaseKeyVaultResourceDefinition
|
||||
implements SpringSupported<KeyVault>, SpringManagedIdentitySupported<KeyVault> {
|
||||
|
||||
public static final KeyVaultResourceDefinition INSTANCE = new KeyVaultResourceDefinition();
|
||||
|
||||
public KeyVaultResourceDefinition() {
|
||||
super("Microsoft.KeyVault", "Azure Key Vault", AzureIcons.KeyVault.MODULE.getIconPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultEnvPrefix() {
|
||||
return "KEY_VAULT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(AzureServiceResource<KeyVault> vaultDef, Project project) {
|
||||
final KeyVault vault = vaultDef.getData();
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
env.put(String.format("%s_ENDPOINT", Connection.ENV_PREFIX), vault.getVaultUri());
|
||||
return env;
|
||||
public AzureFormJPanel<Resource<KeyVault>> getResourcePanel(Project project) {
|
||||
return new KeyVaultResourcePanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,19 +55,42 @@ public class KeyVaultResourceDefinition extends AzureServiceResource.Definition<
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyVault getResource(String dataId, final String id) {
|
||||
return Azure.az(AzureKeyVault.class).getById(dataId);
|
||||
public List<Pair<String, String>> getSpringPropertiesForManagedIdentity(String key, Connection<?, ?> connection) {
|
||||
final ArrayList<Pair<String, String>> result = new ArrayList<>(getSpringProperties(key));
|
||||
result.add(Pair.of("spring.cloud.azure.keyvault.secret.property-sources[0].credential.managed-identity-enabled", String.valueOf(Boolean.TRUE)));
|
||||
if (connection.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
result.add(Pair.of("spring.cloud.azure.keyvault.secret.property-sources[0].credential.client-id", String.format("${%s_CLIENT_ID}", Connection.ENV_PREFIX)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource<KeyVault>> getResources(Project project) {
|
||||
return Azure.az(AzureKeyVault.class).list().stream()
|
||||
.flatMap(m -> m.getKeyVaultModule().list().stream())
|
||||
.map(this::define).toList();
|
||||
public Map<String, String> initIdentityEnv(Connection<KeyVault, ?> data, Project project) {
|
||||
final KeyVault vault = data.getResource().getData();
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
env.put(String.format("%s_ENDPOINT", Connection.ENV_PREFIX), vault.getVaultUri());
|
||||
if (data.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
Optional.ofNullable(data.getUserAssignedManagedIdentity()).map(Resource::getData)
|
||||
.ifPresent(identity -> env.put(String.format("%s_CLIENT_ID", Connection.ENV_PREFIX), identity.getClientId()));
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureFormJPanel<Resource<KeyVault>> getResourcePanel(Project project) {
|
||||
return new KeyVaultResourcePanel();
|
||||
public List<String> getRequiredPermissions() {
|
||||
return List.of(
|
||||
"Microsoft.KeyVault/vaults/secrets/getSecret/action",
|
||||
"Microsoft.KeyVault/vaults/secrets/readMetadata/action",
|
||||
"Microsoft.KeyVault/vaults/keys/read"
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<String, BuiltInRole> getBuiltInRoles() {
|
||||
return Map.of(
|
||||
"4633458b-17de-408a-b874-0445c86b69e6", BuiltInRole.KEY_VAULT_SECRETS_USER,
|
||||
"12338af0-0e69-4776-bea7-57ae8d297424", BuiltInRole.KEY_VAULT_CRYPTO_USER
|
||||
);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ public class KeyVaultResourcePanel implements AzureFormJPanel<Resource<KeyVault>
|
|||
this.vaultComboBox.clear();
|
||||
}
|
||||
});
|
||||
this.vaultComboBox.addValueChangedListener(ignore -> Optional.ofNullable(getValue()).ifPresent(this::fireValueChangedEvent));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +65,7 @@ public class KeyVaultResourcePanel implements AzureFormJPanel<Resource<KeyVault>
|
|||
public Resource<KeyVault> getValue() {
|
||||
final KeyVault cache = this.vaultComboBox.getValue();
|
||||
final AzureValidationInfo info = this.getValidationInfo(true);
|
||||
if (!info.isValid()) {
|
||||
if (info.getType() == AzureValidationInfo.Type.ERROR) {
|
||||
return null;
|
||||
}
|
||||
return KeyVaultResourceDefinition.INSTANCE.define(cache);
|
|
@ -0,0 +1,27 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.keyvault.connection.KeyVaultResourceDefinition"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.keyvault.IntellijJavaKeyVaultActionsContributor"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<completion.confidence id="azKeyVaultValueAnnotation" language="JAVA"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarConfidence"
|
||||
order="before javaSkipAutopopupInStrings"/>
|
||||
<completion.contributor language="JAVA" id="azKeyVaultAnnotationCompletion" order="before azStorageStringLiteral, first"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<completion.contributor language="Properties" id="azKeyVaultPropertiesCompletion" order="before azPropertiesCompletion, first"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<completion.contributor language="yaml" id="azKeyVaultYamlCompletion" order="first, before azYamlCompletion"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="Properties" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="yaml" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="Properties" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="yaml" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<annotator language="Properties" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.PlainTextSecretAnnotator"/>
|
||||
<annotator language="yaml" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.PlainTextSecretAnnotator"/>
|
||||
<typedHandler implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarTypeHandler"/>
|
||||
<lookup.charFilter order="first, before azProperties" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCharFilter"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
|
@ -3,14 +3,12 @@ dependencies {
|
|||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-keyvault-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-keyvault-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
bundledPlugin("com.intellij.java")
|
||||
bundledPlugin("org.jetbrains.plugins.yaml")
|
||||
bundledPlugin("com.intellij.properties")
|
||||
}
|
||||
|
|
|
@ -9,18 +9,12 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
|||
import com.microsoft.azure.toolkit.ide.common.IActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.keyvault.KeyVaultActionsContributor;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.keyvault.connection.KeyVaultResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.keyvault.creation.certificate.CertificateCreationActions;
|
||||
import com.microsoft.azure.toolkit.intellij.keyvault.creation.key.KeyCreationActions;
|
||||
import com.microsoft.azure.toolkit.intellij.keyvault.creation.secret.SecretCreationActions;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.AzureKeyVault;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.CredentialVersion;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.KeyVault;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.certificate.Certificate;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.certificate.CertificateModule;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.key.Key;
|
||||
|
@ -43,13 +37,6 @@ public class IntelliJKeyVaultActionsContributor implements IActionsContributor {
|
|||
am.registerHandler(KeyVaultActionsContributor.GROUP_CREATE_KEY_VAULT, (r, e) -> true,
|
||||
(ResourceGroup group, AnActionEvent e) -> createNewKeyVault(getDefaultConfig(group), e.getProject()));
|
||||
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof KeyVault,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((KeyVault) r), KeyVaultResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
|
||||
final BiPredicate<CredentialVersion, AnActionEvent> certificateCondition = (r, e) -> r instanceof CredentialVersion;
|
||||
am.registerHandler(KeyVaultActionsContributor.DOWNLOAD_CREDENTIAL_VERSION, certificateCondition,
|
||||
(CredentialVersion r, AnActionEvent e) -> KeyVaultCredentialActions.downloadCredential(r, e.getProject()));
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.keyvault.connection;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.AzureKeyVault;
|
||||
import com.microsoft.azure.toolkit.lib.keyvault.KeyVault;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public abstract class BaseKeyVaultResourceDefinition extends AzureServiceResource.Definition<KeyVault> {
|
||||
|
||||
public BaseKeyVaultResourceDefinition() {
|
||||
super("Microsoft.KeyVault", "Azure Key Vault", AzureIcons.KeyVault.MODULE.getIconPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultEnvPrefix() {
|
||||
return "KEY_VAULT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(AzureServiceResource<KeyVault> vaultDef, Project project) {
|
||||
final KeyVault vault = vaultDef.getData();
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
env.put(String.format("%s_ENDPOINT", Connection.ENV_PREFIX), vault.getVaultUri());
|
||||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyVault getResource(String dataId, final String id) {
|
||||
return Azure.az(AzureKeyVault.class).getById(dataId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource<KeyVault>> getResources(Project project) {
|
||||
return Azure.az(AzureKeyVault.class).list().stream()
|
||||
.flatMap(m -> m.getKeyVaultModule().list().stream())
|
||||
.map(this::define).toList();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.keyvault.connection.KeyVaultResourceDefinition"/>
|
||||
<explorerNodeProvider implementation="com.microsoft.azure.toolkit.ide.keyvault.KeyVaultNodeProvider"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.ide.keyvault.KeyVaultActionsContributor"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.keyvault.IntelliJKeyVaultActionsContributor"/>
|
||||
|
@ -13,25 +12,4 @@
|
|||
<fileEditorProvider implementation="com.microsoft.azure.toolkit.intellij.keyvault.property.key.KeyPropertiesEditorProvider"/>
|
||||
<fileEditorProvider implementation="com.microsoft.azure.toolkit.intellij.keyvault.property.key.KeyVersionPropertiesEditorProvider"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<completion.confidence id="azKeyVaultValueAnnotation" language="JAVA"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarConfidence"
|
||||
order="before javaSkipAutopopupInStrings"/>
|
||||
<completion.contributor language="JAVA" id="azKeyVaultAnnotationCompletion" order="before azStorageStringLiteral, first"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<completion.contributor language="Properties" id="azKeyVaultPropertiesCompletion" order="before azPropertiesCompletion, first"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<completion.contributor language="yaml" id="azKeyVaultYamlCompletion" order="first, before azYamlCompletion"
|
||||
implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCompletionContributor"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="Properties" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="yaml" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarReferenceContributor" order="first"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="Properties" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="yaml" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarLineMarkerProvider"/>
|
||||
<annotator language="Properties" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.PlainTextSecretAnnotator"/>
|
||||
<annotator language="yaml" implementationClass="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.PlainTextSecretAnnotator"/>
|
||||
<typedHandler implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarTypeHandler"/>
|
||||
<lookup.charFilter order="first, before azProperties" implementation="com.microsoft.azure.toolkit.intellij.keyvault.code.spring.EnvVarCharFilter"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
dependencies {
|
||||
implementation(project(":azure-intellij-plugin-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-plugin-redis"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-redis", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-redis-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-redis-lib")
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.redis;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.microsoft.azure.toolkit.ide.common.IActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.redis.connection.RedisResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.redis.RedisCache;
|
||||
|
||||
public class IntellijJavaRedisActionsContributor implements IActionsContributor {
|
||||
@Override
|
||||
public void registerHandlers(AzureActionManager am) {
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof RedisCache,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((RedisCache) r), RedisResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.redis.connection;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringSupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.auth.AzureCloud;
|
||||
import com.microsoft.azure.toolkit.redis.RedisCache;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RedisResourceDefinition extends BaseRedisResourceDefinition implements SpringSupported<RedisCache> {
|
||||
public static final RedisResourceDefinition INSTANCE = new RedisResourceDefinition();
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getSpringProperties(@Nullable final String key) {
|
||||
final List<Pair<String, String>> properties = new ArrayList<>();
|
||||
final String suffix = Azure.az(AzureCloud.class).get().getStorageEndpointSuffix();
|
||||
properties.add(Pair.of("spring.data.redis.host", String.format("${%s_HOST}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.port", String.format("${%s_PORT}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.password", String.format("${%s_KEY}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.ssl.enabled", String.format("${%s_SSL}", Connection.ENV_PREFIX)));
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureFormJPanel<Resource<RedisCache>> getResourcePanel(Project project) {
|
||||
return new RedisResourcePanel();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.redis.connection.RedisResourceDefinition"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.redis.IntellijJavaRedisActionsContributor"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
|
@ -3,8 +3,6 @@ dependencies {
|
|||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-redis-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-redis-lib")
|
||||
|
|
|
@ -13,14 +13,10 @@ import com.microsoft.azure.toolkit.ide.redis.RedisActionsContributor;
|
|||
import com.microsoft.azure.toolkit.intellij.common.IntelliJAzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.properties.AzureResourceEditorViewManager;
|
||||
import com.microsoft.azure.toolkit.intellij.common.properties.AzureResourceEditorViewManager.AzureResourceFileType;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.redis.connection.RedisResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.redis.creation.CreateRedisCacheAction;
|
||||
import com.microsoft.azure.toolkit.intellij.redis.explorer.RedisCacheExplorerProvider;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.resource.ResourceGroup;
|
||||
import com.microsoft.azure.toolkit.redis.AzureRedis;
|
||||
import com.microsoft.azure.toolkit.redis.RedisCache;
|
||||
|
@ -38,12 +34,6 @@ public class IntellijRedisActionsContributor implements IActionsContributor {
|
|||
final BiConsumer<Object, AnActionEvent> handler = (c, e) -> CreateRedisCacheAction.create(e.getProject(), null);
|
||||
am.registerHandler(ResourceCommonActionsContributor.CREATE, condition, handler);
|
||||
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof RedisCache,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((RedisCache) r), RedisResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
final Icon icon = IntelliJAzureIcons.getIcon(AzureIcons.RedisCache.MODULE);
|
||||
final String name = RedisCacheExplorerProvider.TYPE;
|
||||
final AzureResourceFileType type = new AzureResourceFileType(name, icon);
|
||||
|
|
|
@ -7,29 +7,21 @@ package com.microsoft.azure.toolkit.intellij.redis.connection;
|
|||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringSupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.auth.AzureCloud;
|
||||
import com.microsoft.azure.toolkit.redis.AzureRedis;
|
||||
import com.microsoft.azure.toolkit.redis.RedisCache;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public class RedisResourceDefinition extends AzureServiceResource.Definition<RedisCache> implements SpringSupported<RedisCache> {
|
||||
public static final RedisResourceDefinition INSTANCE = new RedisResourceDefinition();
|
||||
|
||||
public RedisResourceDefinition() {
|
||||
public abstract class BaseRedisResourceDefinition extends AzureServiceResource.Definition<RedisCache> {
|
||||
public BaseRedisResourceDefinition() {
|
||||
super("Azure.Redis", "Azure Redis Cache", AzureIcons.RedisCache.MODULE.getIconPath());
|
||||
}
|
||||
|
||||
|
@ -44,17 +36,6 @@ public class RedisResourceDefinition extends AzureServiceResource.Definition<Red
|
|||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getSpringProperties(@Nullable final String key) {
|
||||
final List<Pair<String, String>> properties = new ArrayList<>();
|
||||
final String suffix = Azure.az(AzureCloud.class).get().getStorageEndpointSuffix();
|
||||
properties.add(Pair.of("spring.data.redis.host", String.format("${%s_HOST}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.port", String.format("${%s_PORT}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.password", String.format("${%s_KEY}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.data.redis.ssl.enabled", String.format("${%s_SSL}", Connection.ENV_PREFIX)));
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisCache getResource(String dataId, final String id) {
|
||||
return Azure.az(AzureRedis.class).getById(dataId);
|
||||
|
@ -66,9 +47,4 @@ public class RedisResourceDefinition extends AzureServiceResource.Definition<Red
|
|||
.flatMap(m -> m.caches().list().stream())
|
||||
.map(this::define).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureFormJPanel<Resource<RedisCache>> getResourcePanel(Project project) {
|
||||
return new RedisResourcePanel();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.redis.connection.RedisResourceDefinition"/>
|
||||
<explorerNodeProvider implementation="com.microsoft.azure.toolkit.ide.redis.RedisNodeProvider"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.ide.redis.RedisActionsContributor"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.redis.IntellijRedisActionsContributor"/>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
dependencies {
|
||||
implementation(project(":azure-intellij-plugin-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-plugin-storage"))
|
||||
// runtimeOnly project(path: ":azure-intellij-plugin-storage", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-storage-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-storage-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
bundledPlugin("com.intellij.java")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.storage;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.microsoft.azure.toolkit.ide.common.IActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.storage.StorageAccount;
|
||||
|
||||
public class IntellijJavaStorageActionsContributor implements IActionsContributor {
|
||||
@Override
|
||||
public void registerHandlers(AzureActionManager am) {
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof StorageAccount,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((StorageAccount) r), StorageAccountResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.code.function.FunctionUtils;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.BaseStorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.storage.IStorageAccount;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -25,7 +25,7 @@ class Utils {
|
|||
return Optional.of(module).map(AzureModule::from)
|
||||
.map(AzureModule::getDefaultProfile).map(Profile::getConnectionManager).stream()
|
||||
.flatMap(m -> m.getConnections().stream())
|
||||
.filter(c -> c.getDefinition().getResourceDefinition() instanceof StorageAccountResourceDefinition)
|
||||
.filter(c -> c.getDefinition().getResourceDefinition() instanceof BaseStorageAccountResourceDefinition)
|
||||
.filter(c -> Objects.equals(c.getResource().getData(), account))
|
||||
.toList();
|
||||
}
|
|
@ -25,11 +25,11 @@ import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.ModuleResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.code.AnnotationFixes;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.BaseStorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition.TempData;
|
||||
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
|
||||
import com.microsoft.azure.toolkit.lib.storage.ConnectionStringStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.IStorageAccount;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Objects;
|
||||
|
@ -64,7 +64,7 @@ public class ConnectionStringStorageClientAnnotator implements Annotator {
|
|||
.anyMatch(s -> s instanceof ConnectionStringStorageAccount);
|
||||
if (!hasConnectionStringConnection) {
|
||||
final PsiElement parent = element.getParent();
|
||||
final TempData tempData = new TempData(StorageAccountResourceDefinition.METHOD_STRING, null);
|
||||
final TempData tempData = new TempData(BaseStorageAccountResourceDefinition.METHOD_STRING, null);
|
||||
if (parent instanceof PsiLiteralExpression) {
|
||||
final PsiLiteralExpression literal = ((PsiLiteralExpression) parent);
|
||||
final String connectionString = literal.getValue() instanceof String ? (String) literal.getValue() : element.getText();
|
|
@ -28,6 +28,7 @@ import com.microsoft.azure.toolkit.intellij.connector.code.Utils;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.projectexplorer.AbstractAzureFacetNode;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.BaseStorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.auth.AzureAccount;
|
||||
|
@ -131,7 +132,7 @@ public class StoragePathCompletionProvider extends CompletionProvider<Completion
|
|||
return Optional.of(module).map(AzureModule::from)
|
||||
.map(AzureModule::getDefaultProfile).map(Profile::getConnectionManager).stream()
|
||||
.flatMap(m -> m.getConnections().stream())
|
||||
.filter(c -> c.getDefinition().getResourceDefinition() instanceof StorageAccountResourceDefinition)
|
||||
.filter(c -> c.getDefinition().getResourceDefinition() instanceof BaseStorageAccountResourceDefinition)
|
||||
.filter(c -> c.getResource().isValidResource())
|
||||
.toList();
|
||||
}
|
|
@ -5,67 +5,54 @@
|
|||
|
||||
package com.microsoft.azure.toolkit.intellij.storage.connection;
|
||||
|
||||
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceId;
|
||||
import com.azure.resourcemanager.authorization.models.BuiltInRole;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.intellij.common.auth.IntelliJSecureStore;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AuthenticationType;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.function.FunctionSupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringSupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.spring.SpringManagedIdentitySupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.auth.AzureCloud;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzureStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzuriteStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.ConnectionStringStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.IStorageAccount;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static com.microsoft.azure.toolkit.lib.common.model.AbstractConnectionStringAzResourceModule.CONNECTION_STRING_SUBSCRIPTION_ID;
|
||||
|
||||
@Getter
|
||||
public class StorageAccountResourceDefinition extends AzureServiceResource.Definition<IStorageAccount>
|
||||
implements SpringSupported<IStorageAccount>, FunctionSupported<IStorageAccount> {
|
||||
public static final int METHOD_AZURE = 0;
|
||||
public static final int METHOD_AZURITE = 1;
|
||||
public static final int METHOD_STRING = 2;
|
||||
public class StorageAccountResourceDefinition extends BaseStorageAccountResourceDefinition
|
||||
implements SpringManagedIdentitySupported<IStorageAccount> {
|
||||
public static final String CLIENT_ID_KEY = String.format("%s_CLIENT_ID", Connection.ENV_PREFIX);
|
||||
|
||||
public static final StorageAccountResourceDefinition INSTANCE = new StorageAccountResourceDefinition();
|
||||
public static final String LOCAL_STORAGE_CONNECTION_STRING = "UseDevelopmentStorage=true";
|
||||
public static final String CONNECTION_STRING_KEY = String.format("%s_CONNECTION_STRING", Connection.ENV_PREFIX);
|
||||
public static final String ACCOUNT_NAME_KEY = String.format("%s_ACCOUNT_NAME", Connection.ENV_PREFIX);
|
||||
public static final String ACCOUNT_KEY = String.format("%s_ACCOUNT_KEY", Connection.ENV_PREFIX);
|
||||
|
||||
@Setter
|
||||
private TempData tempData;
|
||||
|
||||
public StorageAccountResourceDefinition() {
|
||||
super("Azure.Storage", "Azure Storage Account", AzureIcons.StorageAccount.MODULE.getIconPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(AzureServiceResource<IStorageAccount> accountDef, Project project) {
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
final IStorageAccount account = accountDef.getData();
|
||||
if (Objects.nonNull(account)) {
|
||||
final String conString = account.getConnectionString();
|
||||
env.put(CONNECTION_STRING_KEY, conString);
|
||||
env.put(ACCOUNT_NAME_KEY, account.getName());
|
||||
env.put(ACCOUNT_KEY, account.getKey());
|
||||
public AzureFormJPanel<Resource<IStorageAccount>> getResourcePanel(Project project) {
|
||||
final StorageAccountResourcePanel panel = new StorageAccountResourcePanel();
|
||||
if (Objects.nonNull(this.tempData)) {
|
||||
panel.setMethod(this.tempData.getType());
|
||||
if (StringUtils.isNotBlank(this.tempData.getConnectionString())) {
|
||||
final ConnectionStringStorageAccount account = Azure.az(AzureStorageAccount.class).getOrInitByConnectionString(this.tempData.getConnectionString());
|
||||
if (Objects.nonNull(account)) {
|
||||
panel.setValue(StorageAccountResourceDefinition.INSTANCE.define(account));
|
||||
}
|
||||
}
|
||||
this.tempData = null;
|
||||
}
|
||||
return env;
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,59 +90,64 @@ public class StorageAccountResourceDefinition extends AzureServiceResource.Defin
|
|||
return fields;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IStorageAccount getResource(String dataId, final String id) {
|
||||
if (StringUtils.equalsIgnoreCase(dataId, AzuriteStorageAccount.AZURITE_RESOURCE_ID)) {
|
||||
return AzuriteStorageAccount.AZURITE_STORAGE_ACCOUNT;
|
||||
} else if (CONNECTION_STRING_SUBSCRIPTION_ID.equalsIgnoreCase(ResourceId.fromString(dataId).subscriptionId())) {
|
||||
final String connectionString = IntelliJSecureStore.getInstance().loadPassword(StorageAccountResourceDefinition.class.getName(), id.toLowerCase(), null);
|
||||
if (StringUtils.isNotBlank(connectionString)) {
|
||||
return Azure.az(AzureStorageAccount.class).getOrInitByConnectionString(connectionString);
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return Azure.az(AzureStorageAccount.class).getById(dataId);
|
||||
public Map<String, String> initIdentityEnv(Connection<IStorageAccount, ?> connection, Project project) {
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
final Resource<IStorageAccount> accountDef = connection.getResource();
|
||||
final IStorageAccount account = accountDef.getData();
|
||||
if (Objects.nonNull(account)) {
|
||||
env.put(ACCOUNT_NAME_KEY, account.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource<IStorageAccount>> getResources(Project project) {
|
||||
return Azure.az(AzureStorageAccount.class).list().stream()
|
||||
.flatMap(m -> m.storageAccounts().list().stream())
|
||||
.map(this::define).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureFormJPanel<Resource<IStorageAccount>> getResourcePanel(Project project) {
|
||||
final StorageAccountResourcePanel panel = new StorageAccountResourcePanel();
|
||||
if (Objects.nonNull(this.tempData)) {
|
||||
panel.setMethod(this.tempData.getType());
|
||||
if (StringUtils.isNotBlank(this.tempData.getConnectionString())) {
|
||||
final ConnectionStringStorageAccount account = Azure.az(AzureStorageAccount.class).getOrInitByConnectionString(this.tempData.getConnectionString());
|
||||
if (Objects.nonNull(account)) {
|
||||
panel.setValue(StorageAccountResourceDefinition.INSTANCE.define(account));
|
||||
}
|
||||
}
|
||||
this.tempData = null;
|
||||
if (connection.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
env.put(CLIENT_ID_KEY, Objects.requireNonNull(connection.getUserAssignedManagedIdentity()).getDataId());
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getResourceType() {
|
||||
return "Storage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getEnvironmentVariablesKey() {
|
||||
return ListUtils.union(Arrays.asList(CONNECTION_STRING_KEY, ACCOUNT_NAME_KEY, ACCOUNT_KEY), super.getEnvironmentVariablesKey());
|
||||
return env;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getResourceConnectionString(@Nonnull IStorageAccount resource) {
|
||||
return resource instanceof AzuriteStorageAccount ? LOCAL_STORAGE_CONNECTION_STRING : resource.getConnectionString();
|
||||
public Map<String, BuiltInRole> getBuiltInRoles() {
|
||||
return Map.of("ba92f5b4-2d11-453d-a403-e96b0029c9fe", BuiltInRole.STORAGE_BLOB_DATA_CONTRIBUTOR,
|
||||
"974c5e8b-45b9-4653-ba55-5f855dd0fb88", BuiltInRole.STORAGE_QUEUE_DATA_CONTRIBUTOR,
|
||||
"0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb", BuiltInRole.STORAGE_FILE_DATA_SMB_SHARE_CONTRIBUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredPermissions() {
|
||||
return Arrays.asList(
|
||||
"Microsoft.Storage/storageAccounts/blobServices/containers/delete",
|
||||
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
|
||||
"Microsoft.Storage/storageAccounts/blobServices/containers/write",
|
||||
"Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action",
|
||||
"Microsoft.Storage/storageAccounts/queueServices/queues/delete",
|
||||
"Microsoft.Storage/storageAccounts/queueServices/queues/read",
|
||||
"Microsoft.Storage/storageAccounts/queueServices/queues/write"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getSpringPropertiesForManagedIdentity(String key, Connection<?,?> connection) {
|
||||
final List<Pair<String, String>> properties = new ArrayList<>();
|
||||
final String suffix = Azure.az(AzureCloud.class).get().getStorageEndpointSuffix();
|
||||
if (StringUtils.containsIgnoreCase(key, "blob")) {
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.blob.account-name", String.format("${%s_ACCOUNT_NAME}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.blob.endpoint", String.format("https://${%s_ACCOUNT_NAME}.blob%s", Connection.ENV_PREFIX, suffix)));
|
||||
} else if (StringUtils.containsIgnoreCase(key, "share")) {
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.fileshare.account-name", String.format("${%s_ACCOUNT_NAME}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.fileshare.endpoint", String.format("https://${%s_ACCOUNT_NAME}.file%s", Connection.ENV_PREFIX, suffix)));
|
||||
} else {
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.fileshare.account-name", String.format("${%s_ACCOUNT_NAME}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.fileshare.endpoint", String.format("https://${%s_ACCOUNT_NAME}.file%s", Connection.ENV_PREFIX, suffix)));
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.blob.account-name", String.format("${%s_ACCOUNT_NAME}", Connection.ENV_PREFIX)));
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.blob.endpoint", String.format("https://${%s_ACCOUNT_NAME}.blob%s", Connection.ENV_PREFIX, suffix)));
|
||||
}
|
||||
// properties.add(Pair.of("spring.cloud.azure.storage.blob.credential.managed-identity-enabled", String.valueOf(Boolean.TRUE)));
|
||||
// for user assigned managed identity
|
||||
if (connection.getAuthenticationType() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
properties.add(Pair.of("spring.cloud.azure.storage.blob.credential.client-id", String.format("${%s_CLIENT_ID}", Connection.ENV_PREFIX)));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Data
|
|
@ -78,6 +78,8 @@ public class StorageAccountResourcePanel implements AzureFormJPanel<Resource<ISt
|
|||
lblAccount.setLabelFor(accountComboBox);
|
||||
lblConnectionString.setLabelFor(txtConnectionString);
|
||||
txtConnectionString.setLabel("Connection string");
|
||||
|
||||
this.accountComboBox.addValueChangedListener(ignore -> Optional.ofNullable(getValue()).ifPresent(this::fireValueChangedEvent));
|
||||
}
|
||||
|
||||
private void onSelectEnvironment() {
|
||||
|
@ -133,7 +135,7 @@ public class StorageAccountResourcePanel implements AzureFormJPanel<Resource<ISt
|
|||
@Override
|
||||
public Resource<IStorageAccount> getValue() {
|
||||
final AzureValidationInfo info = this.getValidationInfo(true);
|
||||
if (!info.isValid()) {
|
||||
if (info.getType() == AzureValidationInfo.Type.ERROR) {
|
||||
return null;
|
||||
}
|
||||
final String connectionString = this.txtConnectionString.getValue();
|
|
@ -0,0 +1,20 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.storage.IntellijJavaStorageActionsContributor"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.java.ConnectionStringStorageClientAnnotator"/>
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathAnnotator"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionStorageAccountResourceReferenceContributor"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathLineMarkerProvider"/>
|
||||
<completion.confidence id="azStorageStringLiteral" language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCompletionConfidence" order="before javaSkipAutopopupInStrings"/>
|
||||
<completion.contributor id="azStorageFunctionAnnotation" language="JAVA" order="first" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionAnnotationCompletionContributor"/>
|
||||
<completion.contributor id="azStorageStringLiteralQuick" language="JAVA" order="first, before azStorageStringLiteral" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathPreCompletionContributor"/>
|
||||
<completion.contributor id="azStorageStringLiteral" language="JAVA" order="first" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCompletionContributor"/>
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionAnnotationResourcePathAnnotator"/>
|
||||
<typedHandler id="azStorageSpringValueAnnotation" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathTypeHandler"/>
|
||||
<lookup.charFilter id="azStorageSpringValueAnnotation" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCharFilter"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
|
@ -3,14 +3,7 @@ dependencies {
|
|||
// runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation(project(":azure-intellij-resource-connector-lib-java"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib-java", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-storage-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-storage-lib")
|
||||
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
bundledPlugin("com.intellij.java")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,16 @@ import com.intellij.openapi.project.Project;
|
|||
import com.microsoft.azure.toolkit.ide.common.IActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.ide.storage.StorageActionsContributor;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.azurite.AzuriteService;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.component.StorageCreationDialog;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.creation.CreateStorageAccountAction;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.Action;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResourceModule;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.resource.ResourceGroup;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzureStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.IStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.StorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.blob.BlobContainerModule;
|
||||
import com.microsoft.azure.toolkit.lib.storage.model.StorageAccountConfig;
|
||||
import com.microsoft.azure.toolkit.lib.storage.queue.QueueModule;
|
||||
|
@ -43,13 +38,6 @@ public class IntellijStorageActionsContributor implements IActionsContributor {
|
|||
final BiConsumer<Object, AnActionEvent> handler = (c, e) -> CreateStorageAccountAction.create(e.getProject(), null);
|
||||
am.registerHandler(ResourceCommonActionsContributor.CREATE, condition, handler);
|
||||
|
||||
am.<AzResource, AnActionEvent>registerHandler(ResourceCommonActionsContributor.CONNECT, (r, e) -> r instanceof StorageAccount,
|
||||
(r, e) -> AzureTaskManager.getInstance().runLater(() -> {
|
||||
final ConnectorDialog dialog = new ConnectorDialog(e.getProject());
|
||||
dialog.setResource(new AzureServiceResource<>(((StorageAccount) r), StorageAccountResourceDefinition.INSTANCE));
|
||||
dialog.show();
|
||||
}));
|
||||
|
||||
am.registerHandler(ResourceCommonActionsContributor.CREATE, (m, e) -> m instanceof BlobContainerModule, this::createStorage);
|
||||
am.registerHandler(ResourceCommonActionsContributor.CREATE, (m, e) -> m instanceof ShareModule, this::createStorage);
|
||||
am.registerHandler(ResourceCommonActionsContributor.CREATE, (m, e) -> m instanceof QueueModule, this::createStorage);
|
||||
|
|
|
@ -18,7 +18,7 @@ import com.microsoft.azure.toolkit.intellij.connector.ConnectionTopics;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.ConnectionManager;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.intellij.storage.connection.BaseStorageAccountResourceDefinition;
|
||||
import com.microsoft.azure.toolkit.lib.common.messager.ExceptionNotification;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzuriteStorageAccount;
|
||||
import lombok.SneakyThrows;
|
||||
|
@ -104,7 +104,7 @@ public class AzuriteTaskAdder implements RunManagerListener, ConnectionTopics.Co
|
|||
}
|
||||
|
||||
public static boolean isAzuriteResourceConnection(@Nonnull final Connection<?, ?> connection) {
|
||||
return connection.getDefinition().getResourceDefinition() instanceof StorageAccountResourceDefinition &&
|
||||
return connection.getDefinition().getResourceDefinition() instanceof BaseStorageAccountResourceDefinition &&
|
||||
StringUtils.equalsIgnoreCase(connection.getResource().getDataId(), AzuriteStorageAccount.AZURITE_RESOURCE_ID);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.storage.connection;
|
||||
|
||||
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceId;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.auth.IntelliJSecureStore;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.AzureServiceResource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.function.FunctionSupported;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzureStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.AzuriteStorageAccount;
|
||||
import com.microsoft.azure.toolkit.lib.storage.IStorageAccount;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static com.microsoft.azure.toolkit.lib.common.model.AbstractConnectionStringAzResourceModule.CONNECTION_STRING_SUBSCRIPTION_ID;
|
||||
|
||||
@Getter
|
||||
public abstract class BaseStorageAccountResourceDefinition extends AzureServiceResource.Definition<IStorageAccount> implements FunctionSupported<IStorageAccount> {
|
||||
public static final int METHOD_AZURE = 0;
|
||||
public static final int METHOD_AZURITE = 1;
|
||||
public static final int METHOD_STRING = 2;
|
||||
|
||||
public static final String LOCAL_STORAGE_CONNECTION_STRING = "UseDevelopmentStorage=true";
|
||||
public static final String CONNECTION_STRING_KEY = String.format("%s_CONNECTION_STRING", Connection.ENV_PREFIX);
|
||||
public static final String ACCOUNT_NAME_KEY = String.format("%s_ACCOUNT_NAME", Connection.ENV_PREFIX);
|
||||
public static final String ACCOUNT_KEY = String.format("%s_ACCOUNT_KEY", Connection.ENV_PREFIX);
|
||||
|
||||
public BaseStorageAccountResourceDefinition() {
|
||||
super("Azure.Storage", "Azure Storage Account", AzureIcons.StorageAccount.MODULE.getIconPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(AzureServiceResource<IStorageAccount> accountDef, Project project) {
|
||||
final HashMap<String, String> env = new HashMap<>();
|
||||
final IStorageAccount account = accountDef.getData();
|
||||
if (Objects.nonNull(account)) {
|
||||
final String conString = account.getConnectionString();
|
||||
env.put(CONNECTION_STRING_KEY, conString);
|
||||
env.put(ACCOUNT_NAME_KEY, account.getName());
|
||||
env.put(ACCOUNT_KEY, account.getKey());
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageAccount getResource(String dataId, final String id) {
|
||||
if (StringUtils.equalsIgnoreCase(dataId, AzuriteStorageAccount.AZURITE_RESOURCE_ID)) {
|
||||
return AzuriteStorageAccount.AZURITE_STORAGE_ACCOUNT;
|
||||
} else if (CONNECTION_STRING_SUBSCRIPTION_ID.equalsIgnoreCase(ResourceId.fromString(dataId).subscriptionId())) {
|
||||
final String connectionString = IntelliJSecureStore.getInstance().loadPassword(BaseStorageAccountResourceDefinition.class.getName(), id.toLowerCase(), null);
|
||||
if (StringUtils.isNotBlank(connectionString)) {
|
||||
return Azure.az(AzureStorageAccount.class).getOrInitByConnectionString(connectionString);
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return Azure.az(AzureStorageAccount.class).getById(dataId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource<IStorageAccount>> getResources(Project project) {
|
||||
return Azure.az(AzureStorageAccount.class).list().stream()
|
||||
.flatMap(m -> m.storageAccounts().list().stream())
|
||||
.map(this::define).toList();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getResourceType() {
|
||||
return "Storage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getEnvironmentVariablesKey() {
|
||||
return ListUtils.union(Arrays.asList(CONNECTION_STRING_KEY, ACCOUNT_NAME_KEY, ACCOUNT_KEY), super.getEnvironmentVariablesKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getResourceConnectionString(@Nonnull IStorageAccount resource) {
|
||||
return resource instanceof AzuriteStorageAccount ? LOCAL_STORAGE_CONNECTION_STRING : resource.getConnectionString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,23 +1,10 @@
|
|||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.microsoft.tooling.msservices.intellij.azure">
|
||||
<connectorResourceType implementation="com.microsoft.azure.toolkit.intellij.storage.connection.StorageAccountResourceDefinition"/>
|
||||
<explorerNodeProvider implementation="com.microsoft.azure.toolkit.ide.storage.StorageNodeProvider"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.ide.storage.StorageActionsContributor"/>
|
||||
<actions implementation="com.microsoft.azure.toolkit.intellij.storage.IntellijStorageActionsContributor"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.java.ConnectionStringStorageClientAnnotator"/>
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathAnnotator"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathReferenceContributor" order="first"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionStorageAccountResourceReferenceContributor"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathLineMarkerProvider"/>
|
||||
<completion.confidence id="azStorageStringLiteral" language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCompletionConfidence" order="before javaSkipAutopopupInStrings"/>
|
||||
<completion.contributor id="azStorageFunctionAnnotation" language="JAVA" order="first" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionAnnotationCompletionContributor"/>
|
||||
<completion.contributor id="azStorageStringLiteralQuick" language="JAVA" order="first, before azStorageStringLiteral" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathPreCompletionContributor"/>
|
||||
<completion.contributor id="azStorageStringLiteral" language="JAVA" order="first" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCompletionContributor"/>
|
||||
<annotator language="JAVA" implementationClass="com.microsoft.azure.toolkit.intellij.storage.code.function.FunctionAnnotationResourcePathAnnotator"/>
|
||||
<typedHandler id="azStorageSpringValueAnnotation" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathTypeHandler"/>
|
||||
<lookup.charFilter id="azStorageSpringValueAnnotation" implementation="com.microsoft.azure.toolkit.intellij.storage.code.spring.StoragePathCharFilter"/>
|
||||
<stepsBeforeRunProvider id="AzuriteTaskProviderId" implementation="com.microsoft.azure.toolkit.intellij.storage.azurite.AzuriteTaskProvider"/>
|
||||
</extensions>
|
||||
<projectListeners>
|
||||
|
|
|
@ -6,6 +6,7 @@ dependencies {
|
|||
implementation(project(":azure-intellij-resource-connector-lib"))
|
||||
// runtimeOnly project(path: ":azure-intellij-resource-connector-lib", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package com.microsoft.azure.toolkit.intellij.connector.spring;
|
||||
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.IManagedIdentitySupported;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Resource;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SpringManagedIdentitySupported<T extends AzResource> extends SpringSupported<T>, IManagedIdentitySupported<T> {
|
||||
List<Pair<String, String>> getSpringPropertiesForManagedIdentity(String key, Connection<?,?> connection);
|
||||
}
|
|
@ -17,8 +17,11 @@ import java.util.stream.Collectors;
|
|||
public interface SpringSupported<T> extends ResourceDefinition<T> {
|
||||
static List<Pair<String, String>> getProperties(Connection<?, ?> c, final String propKey) {
|
||||
final ResourceDefinition<?> rd = c.getResource().getDefinition();
|
||||
if (rd instanceof SpringSupported) {
|
||||
return ((SpringSupported<?>) rd).getSpringProperties(propKey).stream()
|
||||
if (rd instanceof SpringSupported<?> springSupported) {
|
||||
final List<Pair<String, String>> springProperties =
|
||||
c.isManagedIdentityConnection() && rd instanceof SpringManagedIdentitySupported<?> si ?
|
||||
si.getSpringPropertiesForManagedIdentity(propKey, c) : springSupported.getSpringProperties(propKey);
|
||||
return springProperties.stream()
|
||||
.map(p -> Pair.of(p.getKey(), p.getValue().replaceAll(Connection.ENV_PREFIX, c.getEnvPrefix())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ dependencies {
|
|||
// runtimeOnly project(path: ":azure-intellij-plugin-service-explorer", configuration: "instrumentedJar")
|
||||
implementation("com.microsoft.azure:azure-toolkit-ide-common-lib")
|
||||
implementation("io.github.cdimascio:dotenv-java:3.0.0")
|
||||
implementation("com.microsoft.azure:azure-toolkit-identity-lib")
|
||||
intellijPlatform {
|
||||
// Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
|
||||
bundledPlugin("com.intellij.properties")
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.connector;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AuthenticationType {
|
||||
SYSTEM_ASSIGNED_MANAGED_IDENTITY("Managed Identity (System Assigned)"),
|
||||
USER_ASSIGNED_MANAGED_IDENTITY("Managed Identity (User Assigned)"),
|
||||
CONNECTION_STRING("Connection String");
|
||||
|
||||
private String displayName;
|
||||
}
|
|
@ -81,12 +81,14 @@ public class AzureServiceResource<T extends AzResource> implements Resource<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(Project project) {
|
||||
public Map<String, String> initEnv(Project project, Connection<?,?> connection) {
|
||||
final T resource = this.getData();
|
||||
if (resource == null || !resource.exists()) {
|
||||
throw new AzureToolkitRuntimeException(String.format("%s '%s' does not exist.", this.getResourceType(), this.getName()));
|
||||
}
|
||||
final Map<String, String> result = new HashMap<>(this.definition.initEnv(this, project));
|
||||
final Map<String, String> properties = connection.isManagedIdentityConnection() && definition instanceof IManagedIdentitySupported identitySupported ?
|
||||
identitySupported.initIdentityEnv(connection, project) : this.definition.initEnv(this, project);
|
||||
final Map<String, String> result = new HashMap<>(properties);
|
||||
if (!(resource instanceof AbstractConnectionStringAzResource<?>)) {
|
||||
result.put(SUBSCRIPTION_ID_KEY, resource.getSubscriptionId());
|
||||
result.put(RESOURCE_GROUP_KEY, resource.getResourceGroupName());
|
||||
|
|
|
@ -12,12 +12,14 @@ import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.function.FunctionSupported;
|
||||
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
|
||||
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import lombok.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jdom.Element;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -52,6 +54,15 @@ public class Connection<R, C> {
|
|||
@Setter
|
||||
protected ConnectionDefinition<R, C> definition;
|
||||
|
||||
@Nullable
|
||||
@Setter
|
||||
protected AuthenticationType authenticationType;
|
||||
|
||||
// todo: change authentication properties to different child class, rather than put them all in connection
|
||||
@Nullable
|
||||
@Setter
|
||||
protected Resource<Identity> userAssignedManagedIdentity;
|
||||
|
||||
@Setter
|
||||
@Getter(AccessLevel.NONE)
|
||||
private String envPrefix;
|
||||
|
@ -77,7 +88,7 @@ public class Connection<R, C> {
|
|||
}
|
||||
|
||||
public Map<String, String> getEnvironmentVariables(final Project project) {
|
||||
final Map<String, String> result = this.resource.initEnv(project).entrySet().stream()
|
||||
final Map<String, String> result = this.resource.initEnv(project, this).entrySet().stream()
|
||||
.collect(Collectors.toMap(e -> e.getKey().replaceAll(Connection.ENV_PREFIX, this.getEnvPrefix()), Map.Entry::getValue));
|
||||
if (this.getResource().getDefinition() instanceof FunctionSupported<R>) {
|
||||
result.putAll(((FunctionSupported<R>) this.getResource().getDefinition()).getPropertiesForFunction(this.getResource().getData(), this));
|
||||
|
@ -134,4 +145,9 @@ public class Connection<R, C> {
|
|||
public List<Pair<String, String>> getGeneratedEnvironmentVariables() {
|
||||
return Optional.ofNullable(this.profile).map(p -> p.getGeneratedEnvironmentVariables(this)).orElse(Collections.emptyList());
|
||||
}
|
||||
|
||||
public boolean isManagedIdentityConnection() {
|
||||
return this.authenticationType == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY ||
|
||||
this.authenticationType == AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.microsoft.azure.toolkit.intellij.common.AzureDialog;
|
|||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.dotazure.Profile;
|
||||
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
@ -75,13 +76,19 @@ public class ConnectionDefinition<R, C> {
|
|||
@SuppressWarnings("unchecked")
|
||||
public Connection<R, C> read(@Nonnull final com.microsoft.azure.toolkit.intellij.connector.dotazure.ResourceManager manager, Element connectionEle) {
|
||||
final String id = connectionEle.getAttributeValue(FIELD_ID);
|
||||
final String envPrefix = connectionEle.getAttributeValue(ENV_PREFIX);
|
||||
final Resource<R> resource = Optional.ofNullable(readResourceFromElement(connectionEle, manager))
|
||||
.orElseGet(() -> new InvalidResource<>(this.getResourceDefinition()));
|
||||
final Resource<C> consumer = Optional.ofNullable(readConsumerFromElement(connectionEle, manager))
|
||||
.orElseGet(() -> new InvalidResource<>(this.getConsumerDefinition()));
|
||||
final Connection<R, C> connection = this.define(id, resource, consumer);
|
||||
connection.setEnvPrefix(envPrefix);
|
||||
Optional.ofNullable(connectionEle.getChild("identity"))
|
||||
.map(ele -> (Resource<Identity>) manager.getResourceById(ele.getTextTrim()))
|
||||
.ifPresent(connection::setUserAssignedManagedIdentity);
|
||||
connection.setEnvPrefix(connectionEle.getAttributeValue(ENV_PREFIX));
|
||||
|
||||
final AuthenticationType authentication = Optional.ofNullable(connectionEle.getAttributeValue("authentication"))
|
||||
.filter(StringUtils::isNotBlank).map(AuthenticationType::valueOf).orElse(AuthenticationType.CONNECTION_STRING);
|
||||
connection.setAuthenticationType(authentication);
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -129,7 +136,14 @@ public class ConnectionDefinition<R, C> {
|
|||
connectionEle.addContent(new Element("consumer")
|
||||
.setAttribute("type", consumer.getDefinition().getName())
|
||||
.setText(consumer.getId()));
|
||||
final Resource<Identity> userAssignedManagedIdentity = connection.getUserAssignedManagedIdentity();
|
||||
if (Objects.nonNull(userAssignedManagedIdentity)) {
|
||||
connectionEle.addContent(new Element("identity")
|
||||
.setAttribute("type", userAssignedManagedIdentity.getDefinition().getName())
|
||||
.setText(userAssignedManagedIdentity.getId()));
|
||||
}
|
||||
connectionEle.setAttribute("envPrefix", connection.getEnvPrefix());
|
||||
connectionEle.setAttribute("authentication", String.valueOf(connection.getAuthenticationType()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.microsoft.azure.toolkit.intellij.connector.ConnectorDialog">
|
||||
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="9" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="580" height="256"/>
|
||||
<xy x="48" y="54" width="721" height="389"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
|
@ -139,9 +139,80 @@
|
|||
</grid>
|
||||
<vspacer id="1a16a">
|
||||
<constraints>
|
||||
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="8493c" binding="pnlAuthentication" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="7" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<visible value="true"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b9b63" class="com.intellij.ui.TitledSeparator" binding="titleAuthentication">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Authentication"/>
|
||||
<titleFont style="1"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="ed670" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<minimum-size width="100" height="24"/>
|
||||
<preferred-size width="100" height="24"/>
|
||||
<maximum-size width="100" height="24"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Type:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5710d" class="com.microsoft.azure.toolkit.intellij.common.AzureComboBox" binding="cbAuthenticationType" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<editable value="true"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="6a0f1" binding="pnlUserAssignedManagedIdentity" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<visible value="false"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="7799a" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<minimum-size width="100" height="24"/>
|
||||
<preferred-size width="100" height="24"/>
|
||||
<maximum-size width="100" height="24"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Identity:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2b748" class="com.microsoft.azure.toolkit.intellij.connector.UserAssignedManagedIdentityComboBox" binding="cbIdentity" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
|
|
@ -25,8 +25,10 @@ import com.microsoft.azure.toolkit.lib.common.action.Action;
|
|||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.form.AzureForm;
|
||||
import com.microsoft.azure.toolkit.lib.common.form.AzureFormInput;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -61,6 +63,11 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
private JTextPane descriptionPane;
|
||||
private JPanel pnlEnvPrefix;
|
||||
private JLabel lblEnvPrefix;
|
||||
private TitledSeparator titleAuthentication;
|
||||
private JPanel pnlAuthentication;
|
||||
private JPanel pnlUserAssignedManagedIdentity;
|
||||
private AzureComboBox<AuthenticationType> cbAuthenticationType;
|
||||
private UserAssignedManagedIdentityComboBox cbIdentity;
|
||||
private SignInHyperLinkLabel signInHyperLinkLabel1;
|
||||
private ResourceDefinition<?> resourceDefinition;
|
||||
private ResourceDefinition<?> consumerDefinition;
|
||||
|
@ -99,6 +106,7 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
}));
|
||||
this.consumerTypeSelector.addItemListener(this::onResourceOrConsumerTypeChanged);
|
||||
this.resourceTypeSelector.addItemListener(this::onResourceOrConsumerTypeChanged);
|
||||
this.cbAuthenticationType.addItemListener(this::onAuthenticationTypeChanged);
|
||||
final Font font = UIManager.getFont("Label.font");
|
||||
final Color foregroundColor = UIManager.getColor("Label.foreground");
|
||||
final Color backgroundColor = UIManager.getColor("Label.backgroundColor");
|
||||
|
@ -119,6 +127,26 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
}
|
||||
}
|
||||
|
||||
private void onSelectResource(Object o) {
|
||||
final AzureServiceResource<?> value = o instanceof AzureServiceResource ? (AzureServiceResource<?>) this.resourcePanel.getValue() : null;
|
||||
if (Objects.nonNull(value)) {
|
||||
cbIdentity.setResource(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAuthenticationTypeChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
final AuthenticationType authenticationType = this.cbAuthenticationType.getValue();
|
||||
this.pnlUserAssignedManagedIdentity.setVisible(authenticationType == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY);
|
||||
if (authenticationType == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
final Resource<?> value = (Resource<?>) this.resourcePanel.getValue();
|
||||
if (value instanceof AzResource azResource) {
|
||||
cbIdentity.setSubscription(azResource.getSubscription());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void onResourceOrConsumerTypeChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED && !tryOpenCustomDialog()) {
|
||||
if (Objects.equals(e.getSource(), this.consumerTypeSelector)) {
|
||||
|
@ -197,6 +225,10 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
if (resource.getDefinition().isEnvPrefixSupported()) {
|
||||
connection.setEnvPrefix(this.envPrefixTextField.getText().trim());
|
||||
}
|
||||
connection.setAuthenticationType(cbAuthenticationType.getValue());
|
||||
if (cbAuthenticationType.getValue() == AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY) {
|
||||
Optional.ofNullable(cbIdentity.getValue()).map(IdentityResource.Definition.INSTANCE::define).ifPresent(connection::setUserAssignedManagedIdentity);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -206,6 +238,9 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
this.setResource(connection.getResource());
|
||||
this.envPrefixTextField.setText(connection.getEnvPrefix());
|
||||
this.connection = connection;
|
||||
// authentication
|
||||
this.cbAuthenticationType.setValue(ObjectUtils.firstNonNull(connection.getAuthenticationType(), AuthenticationType.CONNECTION_STRING));
|
||||
Optional.ofNullable(connection.getUserAssignedManagedIdentity()).map(Resource::getData).ifPresent(cbIdentity::setValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -246,8 +281,16 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
this.envPrefixTextField.setText(definition.getDefaultEnvPrefix());
|
||||
this.resourceTypeSelector.setValue(new ItemReference<>(definition.getName(), ResourceDefinition::getName));
|
||||
this.resourcePanel = this.updatePanel(definition, this.resourcePanelContainer);
|
||||
Optional.ofNullable(this.resourcePanel).ifPresent(panel -> panel.addValueChangedListener(this::onSelectResource));
|
||||
|
||||
this.lblEnvPrefix.setVisible(resourceDefinition.isEnvPrefixSupported());
|
||||
this.envPrefixTextField.setVisible(resourceDefinition.isEnvPrefixSupported());
|
||||
|
||||
final List<AuthenticationType> supportedAuthenticationTypes = definition.getSupportedAuthenticationTypes();
|
||||
this.pnlAuthentication.setVisible(supportedAuthenticationTypes.size() > 1);
|
||||
this.cbAuthenticationType.clear();
|
||||
this.cbAuthenticationType.setItemsLoader(() -> supportedAuthenticationTypes);
|
||||
this.cbAuthenticationType.reloadItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,6 +340,25 @@ public class ConnectorDialog extends AzureDialog<Connection<?, ?>> implements Az
|
|||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
this.cbIdentity = new UserAssignedManagedIdentityComboBox();
|
||||
this.cbAuthenticationType = new AzureComboBox<>() {
|
||||
@Nullable
|
||||
@Override
|
||||
protected AuthenticationType doGetDefaultValue() {
|
||||
return AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected List<ExtendableTextComponent.Extension> getExtensions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getItemText(Object item) {
|
||||
return item instanceof AuthenticationType type ? type.getDisplayName() : super.getItemText(item);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setDescription(@Nonnull final String description) {
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
package com.microsoft.azure.toolkit.intellij.connector;
|
||||
|
||||
import com.azure.resourcemanager.authorization.models.BuiltInRole;
|
||||
import com.azure.resourcemanager.authorization.models.RoleAssignment;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.action.ResourceCommonActionsContributor;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.Action;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.AzureActionManager;
|
||||
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Interfaced to indicate that the resource supports managed identity
|
||||
* <p>
|
||||
*/
|
||||
public interface IManagedIdentitySupported<T extends AzResource> {
|
||||
String FAILED_TO_ASSIGN_MESSAGE = "Failed to grant permission to identity <a href=\"%s\">%s</a>, %s, please try assign correct role to it in portal";
|
||||
|
||||
Map<String, String> initIdentityEnv(Connection<T, ?> data, Project project);
|
||||
|
||||
/**
|
||||
* Get required permissions to access the target resource
|
||||
*
|
||||
* @return List of required permissions
|
||||
*/
|
||||
List<String> getRequiredPermissions();
|
||||
|
||||
/**
|
||||
* Get built-in roles that could be assigned to the identity to get access to target resource
|
||||
*
|
||||
* @return Map (role id, BuildInRole), refers https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
|
||||
*/
|
||||
@Nullable Map<String, BuiltInRole> getBuiltInRoles();
|
||||
|
||||
/**
|
||||
* Check whether identity has required permissions to access resource
|
||||
*/
|
||||
public static boolean checkPermission(@Nonnull AzureServiceResource<?> data, @Nonnull String identity) {
|
||||
final AzureServiceResource.Definition<?> d = data.getDefinition();
|
||||
final AzResource r = data.getData();
|
||||
if (d instanceof IManagedIdentitySupported<?> definition && r instanceof AbstractAzResource<?, ?, ?> resource) {
|
||||
final List<String> permissions = resource.getPermissions(identity);
|
||||
final List<String> requiredPermissions = definition.getRequiredPermissions();
|
||||
return CollectionUtils.containsAll(permissions, requiredPermissions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Action<?> getOpenIdentityConfigurationAction(@Nonnull AzureServiceResource<?> data) {
|
||||
final String url = Objects.requireNonNull(data.getData()).getPortalUrl() + "/iamAccessControl";
|
||||
return AzureActionManager.getInstance().getAction(ResourceCommonActionsContributor.OPEN_URL).bind(url).withLabel("Open IAM Configuration");
|
||||
}
|
||||
|
||||
public static boolean grantPermission(@Nonnull AzureServiceResource<?> data, @Nonnull String identity) {
|
||||
final AzureServiceResource.Definition<?> d = data.getDefinition();
|
||||
final AzResource r = data.getData();
|
||||
if (d instanceof IManagedIdentitySupported<?> definition && MapUtils.isNotEmpty(definition.getBuiltInRoles()) && r instanceof AbstractAzResource<?, ?, ?> resource) {
|
||||
final Map<String, BuiltInRole> builtInRoles = definition.getBuiltInRoles();
|
||||
final List<String> roles = resource.getRoleAssignments(identity).stream().map(RoleAssignment::roleDefinitionId).toList();
|
||||
final String rolesStr = builtInRoles.values().stream().map(BuiltInRole::toString).collect(Collectors.joining(","));
|
||||
final boolean assignRole = AzureMessager.getDefaultMessager().confirm(String.format("Do you want to assign roles (%s) to identity (%s)?", rolesStr, identity), "Assign Required Roles");
|
||||
if (assignRole) {
|
||||
try {
|
||||
Objects.requireNonNull(definition.getBuiltInRoles()).forEach((id, role) -> {
|
||||
if (roles.stream().noneMatch(ro -> ro.endsWith(id))) {
|
||||
AzureMessager.getMessager().info(String.format("Assigning role (%s) to identity (%s)...", role, identity));
|
||||
resource.grantPermissionToIdentity(identity, role);
|
||||
}
|
||||
});
|
||||
AzureMessager.getMessager().info(String.format("Roles (%s) have been assigned to identity (%s)?", rolesStr, identity));
|
||||
return true;
|
||||
} catch (final RuntimeException e) {
|
||||
final String errorMessage = String.format(FAILED_TO_ASSIGN_MESSAGE, resource.getPortalUrl(), identity, e.getMessage());
|
||||
AzureMessager.getMessager().warning(errorMessage, getOpenIdentityConfigurationAction(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Action<?> getGrantPermissionAction(@Nonnull AzureServiceResource<?> data, @Nonnull String identity) {
|
||||
final AzureServiceResource.Definition<?> d = data.getDefinition();
|
||||
final AzResource r = data.getData();
|
||||
if (d instanceof IManagedIdentitySupported<?> definition && MapUtils.isNotEmpty(definition.getBuiltInRoles()) && r instanceof AbstractAzResource<?, ?, ?> resource) {
|
||||
return new Action<>(Action.Id.of("user/common.assign_role.identity"))
|
||||
.withLabel("Assign Required Roles")
|
||||
.withIdParam(identity)
|
||||
.withHandler(ignore -> grantPermission(data, identity));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.connector;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.microsoft.azure.toolkit.ide.common.icon.AzureIcons;
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureFormJPanel;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
|
||||
import com.microsoft.azure.toolkit.lib.identities.AzureManagedIdentity;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class IdentityResource extends AzureServiceResource<Identity> {
|
||||
public IdentityResource(@Nonnull Identity data, @Nonnull AzureServiceResource.Definition<Identity> definition) {
|
||||
super(data, definition);
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class Definition extends AzureServiceResource.Definition<Identity> {
|
||||
public static final Definition INSTANCE = new Definition();
|
||||
|
||||
public Definition() {
|
||||
super("Managed Identity", "Managed Identity", AzureIcons.Common.AZURE.getIconPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource<Identity> define(Identity resource) {
|
||||
return super.define(resource, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identity getResource(String dataId, final String id) {
|
||||
return Azure.az(AzureManagedIdentity.class).getById(dataId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(AzureServiceResource<Identity> data, Project project) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRole() {
|
||||
return IDENTITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AzureFormJPanel<Resource<Identity>> getResourcePanel(Project project) {
|
||||
throw new AzureToolkitRuntimeException("not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource<Identity>> getResources(Project project) {
|
||||
throw new AzureToolkitRuntimeException("not supported");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,10 @@ public interface Resource<T> {
|
|||
default void navigate(AnActionEvent event) {
|
||||
}
|
||||
|
||||
default Map<String, String> initEnv(Project project, Connection<?,?> connection) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
default Map<String, String> initEnv(Project project) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@ import org.jdom.Element;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface ResourceDefinition<T> {
|
||||
int RESOURCE = 1;
|
||||
int CONSUMER = 2;
|
||||
int IDENTITY = 4;
|
||||
int BOTH = RESOURCE | CONSUMER;
|
||||
|
||||
/**
|
||||
|
@ -77,4 +79,14 @@ public interface ResourceDefinition<T> {
|
|||
default String getDefaultEnvPrefix() {
|
||||
return this.getName().toUpperCase().replaceAll("[^a-zA-Z0-9]", "_");
|
||||
}
|
||||
|
||||
default List<AuthenticationType> getSupportedAuthenticationTypes() {
|
||||
final List<AuthenticationType> result = new ArrayList<>();
|
||||
result.add(AuthenticationType.CONNECTION_STRING);
|
||||
if (this instanceof IManagedIdentitySupported) {
|
||||
result.add(AuthenticationType.SYSTEM_ASSIGNED_MANAGED_IDENTITY);
|
||||
result.add(AuthenticationType.USER_ASSIGNED_MANAGED_IDENTITY);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.azure.toolkit.intellij.connector;
|
||||
|
||||
import com.microsoft.azure.toolkit.intellij.common.AzureComboBox;
|
||||
import com.microsoft.azure.toolkit.lib.Azure;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.Subscription;
|
||||
import com.microsoft.azure.toolkit.lib.identities.AzureManagedIdentity;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.ComparatorUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
|
||||
import static com.microsoft.azure.toolkit.intellij.connector.IManagedIdentitySupported.checkPermission;
|
||||
|
||||
public class UserAssignedManagedIdentityComboBox extends AzureComboBox<Identity> {
|
||||
@Getter
|
||||
private AzureServiceResource<?> resource;
|
||||
@Getter
|
||||
private Subscription subscription;
|
||||
private final Map<Identity, Boolean> permissions = new HashMap<>();
|
||||
|
||||
public UserAssignedManagedIdentityComboBox() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setSubscription(Subscription subscription) {
|
||||
if (Objects.equals(subscription, this.subscription)) {
|
||||
return;
|
||||
}
|
||||
this.subscription = subscription;
|
||||
if (subscription == null) {
|
||||
this.clear();
|
||||
return;
|
||||
}
|
||||
this.reloadItems();
|
||||
}
|
||||
|
||||
public void setResource(AzureServiceResource<?> azResource) {
|
||||
if (Objects.equals(azResource, this.resource)) {
|
||||
return;
|
||||
}
|
||||
this.clear();
|
||||
this.resource = azResource;
|
||||
this.subscription = Optional.ofNullable(azResource.getData()).map(AzResource::getSubscription).orElse(null);
|
||||
this.reloadItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getItemText(Object item) {
|
||||
if (item instanceof Identity identity) {
|
||||
return Objects.isNull(resource) || BooleanUtils.isTrue(permissions.get(identity)) ?
|
||||
identity.getName() : String.format("%s (No permission)", identity.getName());
|
||||
}
|
||||
return super.getItemText(item);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected List<Identity> loadItems() throws Exception {
|
||||
final List<Identity> identities = Objects.isNull(subscription) ?
|
||||
Azure.az(AzureManagedIdentity.class).identities() :
|
||||
Azure.az(AzureManagedIdentity.class).forSubscription(this.subscription.getId()).identity().list();
|
||||
if (Objects.isNull(resource)) {
|
||||
return identities;
|
||||
}
|
||||
permissions.clear();
|
||||
identities.forEach(identity -> permissions.put(identity, checkPermission(resource, identity.getPrincipalId())));
|
||||
identities.sort(Comparator.comparing(permissions::get).reversed());
|
||||
return identities;
|
||||
}
|
||||
}
|
|
@ -9,16 +9,17 @@ import com.intellij.openapi.application.ApplicationManager;
|
|||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.Connection;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.ConnectionTopics;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.DeploymentTargetTopics;
|
||||
import com.microsoft.azure.toolkit.intellij.connector.*;
|
||||
import com.microsoft.azure.toolkit.intellij.facet.AzureFacet;
|
||||
import com.microsoft.azure.toolkit.lib.common.action.Action;
|
||||
import com.microsoft.azure.toolkit.lib.common.bundle.AzureString;
|
||||
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
|
||||
import com.microsoft.azure.toolkit.lib.common.messager.AzureMessager;
|
||||
import com.microsoft.azure.toolkit.lib.common.model.AbstractAzResource;
|
||||
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
|
||||
import com.microsoft.azure.toolkit.lib.common.operation.OperationBundle;
|
||||
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
|
||||
import com.microsoft.azure.toolkit.lib.identities.Identity;
|
||||
import io.github.cdimascio.dotenv.internal.DotenvParser;
|
||||
import io.github.cdimascio.dotenv.internal.DotenvReader;
|
||||
import lombok.Getter;
|
||||
|
@ -33,20 +34,17 @@ import java.io.IOException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.microsoft.azure.toolkit.intellij.connector.ConnectionTopics.CONNECTION_CHANGED;
|
||||
import static com.microsoft.azure.toolkit.intellij.connector.IManagedIdentitySupported.*;
|
||||
import static com.microsoft.azure.toolkit.intellij.connector.dotazure.AzureModule.DOT_ENV;
|
||||
|
||||
@Getter
|
||||
public class Profile {
|
||||
public static final String NO_PERMISSION_MESSAGE = "The managed identity <a href=\"%s\">%s</a> (%s) doesn't have enough permission to access resource %s.";
|
||||
@Nonnull
|
||||
private final String name;
|
||||
@Nonnull
|
||||
|
@ -98,8 +96,23 @@ public class Profile {
|
|||
|
||||
public synchronized Future<?> addConnection(@Nonnull Connection<?, ?> connection) {
|
||||
AzureFacet.addTo(this.module.getModule());
|
||||
this.resourceManager.addResource(connection.getResource());
|
||||
final Resource<?> resource = connection.getResource();
|
||||
this.resourceManager.addResource(resource);
|
||||
this.connectionManager.addConnection(connection);
|
||||
// handle user assigned managed identity
|
||||
final Resource<Identity> identityResource = connection.getUserAssignedManagedIdentity();
|
||||
if (Objects.nonNull(identityResource)) {
|
||||
this.resourceManager.addResource(identityResource);
|
||||
AzureTaskManager.getInstance().runInBackground("Validating connection", () -> {
|
||||
final String identity = identityResource.getData().getPrincipalId();
|
||||
if (resource instanceof AzureServiceResource<?> serviceResource && !checkPermission(serviceResource, identity)) {
|
||||
final String message = String.format(NO_PERMISSION_MESSAGE, identityResource.getData().getPortalUrl(), identityResource.getName(),identityResource.getData().getPrincipalId(), resource.getName());
|
||||
final Action<?> openIdentityConfigurationAction = getOpenIdentityConfigurationAction(serviceResource);
|
||||
final Action<?> grantPermissionAction = getGrantPermissionAction(serviceResource, identity);
|
||||
AzureMessager.getMessager().warning(message, grantPermissionAction, openIdentityConfigurationAction);
|
||||
}
|
||||
});
|
||||
}
|
||||
return this.addConnectionToDotEnv(connection);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public class KeyValueResource implements Resource<KeyValueData> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> initEnv(Project project) {
|
||||
public Map<String, String> initEnv(Project project, Connection<?,?> ignore) {
|
||||
final KeyValueData connection = getData();
|
||||
return Collections.singletonMap(connection.getKey(), connection.getValue());
|
||||
}
|
||||
|
|
|
@ -66,15 +66,15 @@ allprojects {
|
|||
// jetbrainsRuntime()
|
||||
}
|
||||
|
||||
implementation(platform("com.microsoft.azure:azure-toolkit-libs:0.47.0-SNAPSHOT"))
|
||||
implementation(platform("com.microsoft.azure:azure-toolkit-ide-libs:0.47.0-SNAPSHOT"))
|
||||
implementation(platform("com.microsoft.azure:azure-toolkit-libs:0.47.0"))
|
||||
implementation(platform("com.microsoft.azure:azure-toolkit-ide-libs:0.47.0"))
|
||||
implementation(platform("com.microsoft.hdinsight:azure-toolkit-ide-hdinsight-libs:0.1.1"))
|
||||
|
||||
compileOnly("org.projectlombok:lombok:1.18.24")
|
||||
compileOnly("org.jetbrains:annotations:24.0.0")
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.24")
|
||||
implementation("com.microsoft.azure:azure-toolkit-common-lib:0.47.0-SNAPSHOT")
|
||||
aspect("com.microsoft.azure:azure-toolkit-common-lib:0.47.0-SNAPSHOT")
|
||||
implementation("com.microsoft.azure:azure-toolkit-common-lib:0.47.0")
|
||||
aspect("com.microsoft.azure:azure-toolkit-common-lib:0.47.0")
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
@ -176,6 +176,7 @@ dependencies {
|
|||
implementation(project(":azure-sdk-reference-book"))
|
||||
implementation(project(":azure-intellij-plugin-springcloud"))
|
||||
implementation(project(":azure-intellij-plugin-storage"))
|
||||
implementation(project(":azure-intellij-plugin-storage-java"))
|
||||
implementation(project(":azure-intellij-plugin-appservice"))
|
||||
implementation(project(":azure-intellij-plugin-appservice-java"))
|
||||
implementation(project(":azure-intellij-plugin-arm"))
|
||||
|
@ -190,11 +191,13 @@ dependencies {
|
|||
implementation(project(":azure-intellij-plugin-database-java"))
|
||||
implementation(project(":azure-intellij-plugin-vm"))
|
||||
implementation(project(":azure-intellij-plugin-redis"))
|
||||
implementation(project(":azure-intellij-plugin-redis-java"))
|
||||
implementation(project(":azure-intellij-plugin-samples"))
|
||||
implementation(project(":azure-intellij-plugin-bicep"))
|
||||
implementation(project(":azure-intellij-plugin-eventhubs"))
|
||||
implementation(project(":azure-intellij-plugin-servicebus"))
|
||||
implementation(project(":azure-intellij-plugin-keyvault"))
|
||||
implementation(project(":azure-intellij-plugin-keyvault-java"))
|
||||
implementation(project(":azure-intellij-resource-connector-aad"))
|
||||
implementation(project(":azure-intellij-plugin-hdinsight-lib"))
|
||||
implementation(project(":azure-intellij-plugin-sqlserverbigdata"))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pluginVersion=3.91.0-SNAPSHOT
|
||||
pluginVersion=3.91.0
|
||||
intellijDisplayVersion=2024.2
|
||||
intellij_version=IU-242-EAP-SNAPSHOT
|
||||
platformVersion=242-EAP-SNAPSHOT
|
||||
|
|
|
@ -18,6 +18,7 @@ include("azure-intellij-plugin-guidance-java")
|
|||
include("azure-sdk-reference-book")
|
||||
include("azure-intellij-plugin-springcloud")
|
||||
include("azure-intellij-plugin-storage")
|
||||
include("azure-intellij-plugin-storage-java")
|
||||
include("azure-intellij-plugin-appservice")
|
||||
include("azure-intellij-plugin-appservice-java")
|
||||
include("azure-intellij-plugin-arm")
|
||||
|
@ -32,6 +33,7 @@ include("azure-intellij-plugin-database")
|
|||
include("azure-intellij-plugin-database-java")
|
||||
include("azure-intellij-plugin-vm")
|
||||
include("azure-intellij-plugin-redis")
|
||||
include("azure-intellij-plugin-redis-java")
|
||||
include("azure-intellij-plugin-samples")
|
||||
include("azure-intellij-plugin-bicep")
|
||||
include("azure-intellij-plugin-eventhubs")
|
||||
|
@ -44,4 +46,5 @@ include("azure-intellij-plugin-synapse")
|
|||
include("azure-intellij-plugin-sparkoncosmos")
|
||||
include("azure-intellij-plugin-sqlserverbigdata")
|
||||
include("azure-intellij-plugin-keyvault")
|
||||
include("azure-intellij-plugin-keyvault-java")
|
||||
include("azure-intellij-plugin-integration-services")
|
|
@ -2,7 +2,7 @@
|
|||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<id>com.microsoft.tooling.msservices.intellij.azure</id>
|
||||
<name>Azure Toolkit for IntelliJ</name>
|
||||
<version>3.91.0-SNAPSHOT</version>
|
||||
<version>3.91.0</version>
|
||||
<vendor email="java@microsoft.com" url="http://www.microsoft.com">Microsoft</vendor>
|
||||
|
||||
<description><![CDATA[
|
||||
|
@ -54,6 +54,7 @@
|
|||
<xi:include href="/META-INF/azure-sdk-reference-book.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-springcloud.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-storage.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-storage-java.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-appservice.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-appservice-java.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-arm.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
@ -68,11 +69,13 @@
|
|||
<xi:include href="/META-INF/azure-intellij-plugin-database-java.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-vm.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-redis.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-redis-java.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-samples.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-bicep.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-eventhubs.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-servicebus.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-keyvault.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-keyvault-java.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-resource-connector-aad.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-hdinsight.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/azure-intellij-plugin-sqlserverbigdata.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<azure.toolkit-lib.version>0.47.0-SNAPSHOT</azure.toolkit-lib.version>
|
||||
<azure.toolkit-ide-lib.version>0.47.0-SNAPSHOT</azure.toolkit-ide-lib.version>
|
||||
<azure.toolkit-lib.version>0.47.0</azure.toolkit-lib.version>
|
||||
<azure.toolkit-ide-lib.version>0.47.0</azure.toolkit-ide-lib.version>
|
||||
<hdinsight.toolkit-ide-lib.version>0.1.1</hdinsight.toolkit-ide-lib.version>
|
||||
<gson.version>2.9.0</gson.version>
|
||||
<kotlin.version>1.9.10</kotlin.version>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>azure-toolkit-ide-libs</artifactId>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>azure-toolkit-ide-libs</artifactId>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>azure-toolkit-ide-libs</artifactId>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<artifactId>azure-toolkit-ide-libs</artifactId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>azure-toolkit-ide-cognitiveservices-lib</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>azure-toolkit-ide-libs</artifactId>
|
||||
<groupId>com.microsoft.azure</groupId>
|
||||
<version>0.47.0-SNAPSHOT</version>
|
||||
<version>0.47.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче