Skip to content

Commit

Permalink
[plugin-azure-key-vault] Add step to collect key vault properties via…
Browse files Browse the repository at this point in the history
… management API (vividus-framework#2491)
  • Loading branch information
valfirst authored and Vitaliya Piliuhina committed Apr 7, 2022
1 parent a2924cf commit bf93334
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/modules/plugins/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*** xref:plugin-azure-event-grid.adoc[Event Grid]
*** xref:plugin-azure-event-hub.adoc[Event Hub]
*** xref:plugin-azure-functions.adoc[Functions]
*** xref:plugin-azure-key-vault.adoc[Key Vault]
*** xref:plugin-azure-storage-account.adoc[Storage Account]
*** xref:plugin-azure-storage-queue.adoc[Storage Queue]
* Data Formats
Expand Down
45 changes: 45 additions & 0 deletions docs/modules/plugins/pages/plugin-azure-key-vault.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
:azure-service-name: key-vault

= Azure Key Vault Plugin

The plugin provides functionality to interact with https://docs.microsoft.com/en-us/azure/key-vault/[Azure Key Vault].

== Installation

.build.gradle
[source,gradle,subs="attributes+"]
----
implementation(group: 'org.vividus', name: 'vividus-plugin-azure-key-vault', version: '{current-version}')
----

== Key Vault management

=== Configuration

include::partial$azure-authentication.adoc[leveloffset=+1]

include::partial$azure-profile-and-subscription.adoc[leveloffset=+1]

=== Steps

==== Retrieve the Key Vault properties

Retrieves the properties of the specified Azure key vault and saves them as JSON
to a variable. For more information, see the
https://docs.microsoft.com/en-us/rest/api/keyvault/keyvault/vaults/get[Azure Docs].

[source,gherkin]
----
When I retrieve properties of key vault with name `$keyVaultName` from resource group `$resourceGroupName` and save them as JSON to $scopes variable `$variableName`
----

* `$keyVaultName` - The name of the key vault within the specified resource group.
* `$resourceGroupName` - The name of the resource group within the user's subscription to retrieve the key vault from. The name is case-insensitive.
* `$scopes` - xref:commons:variables.adoc#_scopes[The comma-separated set of the variables scopes].
* `$variableName` - The variable name to store the key vault properties as JSON.

.Retrieve the Key Vault properties
[source,gherkin]
----
When I retrieve properties of key vault with name `KEY-VAULT-NAME` from resource group `TEST-SA` and save them as JSON to scenario variable `key-vault-properties`
----
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ include 'vividus-plugin-azure-data-factory'
include 'vividus-plugin-azure-event-grid'
include 'vividus-plugin-azure-event-hub'
include 'vividus-plugin-azure-functions'
include 'vividus-plugin-azure-key-vault'
include 'vividus-plugin-azure-storage-account'
include 'vividus-plugin-azure-storage-queue'
include 'vividus-plugin-browserstack'
Expand Down
1 change: 1 addition & 0 deletions vividus-docker-bundler/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies {
implementation project(':vividus-plugin-azure-event-grid')
implementation project(':vividus-plugin-azure-event-hub')
implementation project(':vividus-plugin-azure-functions')
implementation project(':vividus-plugin-azure-key-vault')
implementation project(':vividus-plugin-azure-storage-account')
implementation project(':vividus-plugin-azure-storage-queue')
implementation project(':vividus-plugin-browserstack')
Expand Down
11 changes: 11 additions & 0 deletions vividus-plugin-azure-key-vault/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
project.description = 'Vividus plugin for Azure Key Vault'

dependencies {
api project(':vividus-engine')
implementation project(':vividus-extension-azure')
implementation(group: 'com.azure.resourcemanager', name: 'azure-resourcemanager-keyvault', version: '2.11.0')

testImplementation platform(group: 'org.junit', name: 'junit-bom', version: versions.junit)
testImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter')
testImplementation(group: 'org.mockito', name: 'mockito-junit-jupiter', version: versions.mockito)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.azure.keyvault;

import java.io.IOException;
import java.util.Set;

import com.azure.core.credential.TokenCredential;
import com.azure.core.management.profile.AzureProfile;
import com.azure.resourcemanager.keyvault.KeyVaultManager;
import com.azure.resourcemanager.keyvault.fluent.models.VaultInner;

import org.jbehave.core.annotations.When;
import org.vividus.azure.util.InnersJacksonAdapter;
import org.vividus.context.VariableContext;
import org.vividus.variable.VariableScope;

public class KeyVaultManagementSteps
{
private final KeyVaultManager keyVaultManager;
private final VariableContext variableContext;
private final InnersJacksonAdapter innersJacksonAdapter;

public KeyVaultManagementSteps(AzureProfile azureProfile, TokenCredential tokenCredential,
InnersJacksonAdapter innersJacksonAdapter, VariableContext variableContext)
{
this.keyVaultManager = KeyVaultManager.authenticate(tokenCredential, azureProfile);
this.variableContext = variableContext;
this.innersJacksonAdapter = innersJacksonAdapter;
}

/**
* Retrieves the properties of the specified Azure key vault and saves them as JSON to a variable. For more
* information, see the
* <a href="https://docs.microsoft.com/en-us/rest/api/keyvault/keyvault/vaults/get">Azure Docs</a>.
*
* @param keyVaultName The name of the key vault within the specified resource group.
* @param resourceGroupName The name of the resource group within the user's subscription to retrieve the key
* vault from. The name is case-insensitive.
* @param scopes The set (comma separated list of scopes e.g.: STORY, NEXT_BATCHES) of the variable
* scopes.<br>
* <i>Available scopes:</i>
* <ul>
* <li><b>STEP</b> - the variable will be available only within the step,
* <li><b>SCENARIO</b> - the variable will be available only within the scenario,
* <li><b>STORY</b> - the variable will be available within the whole story,
* <li><b>NEXT_BATCHES</b> - the variable will be available starting from next batch
* </ul>
* @param variableName The variable name to store the key vault properties as JSON.
* @throws IOException If an input or output exception occurred
*/
@When("I retrieve properties of key vault with name `$keyVaultName` from resource group `$resourceGroupName` and "
+ "save them as JSON to $scopes variable `$variableName`")
public void retrieveKeyVaultProperties(String keyVaultName, String resourceGroupName, Set<VariableScope> scopes,
String variableName) throws IOException
{
VaultInner vault = keyVaultManager.serviceClient()
.getVaults()
.getByResourceGroup(resourceGroupName, keyVaultName);

variableContext.putVariable(scopes, variableName, innersJacksonAdapter.serializeToJson(vault));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
azure.key-vault.environment=${azure.environment}
20 changes: 20 additions & 0 deletions vividus-plugin-azure-key-vault/src/main/resources/spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"
default-lazy-init="true">

<bean id="keyVaultManagementSteps" class="org.vividus.azure.keyvault.KeyVaultManagementSteps">
<constructor-arg>
<bean class="com.azure.core.management.profile.AzureProfile">
<constructor-arg type="com.azure.core.management.AzureEnvironment" value="${azure.key-vault.environment}" />
</bean>
</constructor-arg>
</bean>

<util:list id="stepBeanNames-Azure-KeyVault" value-type="java.lang.String">
<idref bean="keyVaultManagementSteps" />
</util:list>
</beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.azure.keyvault;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.Set;

import com.azure.core.credential.TokenCredential;
import com.azure.core.management.profile.AzureProfile;
import com.azure.resourcemanager.keyvault.KeyVaultManager;
import com.azure.resourcemanager.keyvault.fluent.KeyVaultManagementClient;
import com.azure.resourcemanager.keyvault.fluent.VaultsClient;
import com.azure.resourcemanager.keyvault.fluent.models.VaultInner;
import com.azure.resourcemanager.keyvault.models.VaultProperties;

import org.apache.commons.lang3.function.FailableBiConsumer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.vividus.azure.util.InnersJacksonAdapter;
import org.vividus.context.VariableContext;
import org.vividus.variable.VariableScope;

@ExtendWith(MockitoExtension.class)
class KeyVaultManagementStepsTests
{
private static final String RESOURCE_GROUP_NAME = "resourceGroupName";
private static final Set<VariableScope> SCOPES = Set.of(VariableScope.STORY);
private static final String VAR_NAME = "varName";

@Mock private AzureProfile azureProfile;
@Mock private TokenCredential tokenCredential;
@Mock private VariableContext variableContext;

@Test
void shouldRetrieveKeyVaultProperties() throws IOException
{
runWithKeyVaultClient((keyVaultManagementClient, steps) ->
{
var vaultsClient = mock(VaultsClient.class);
when(keyVaultManagementClient.getVaults()).thenReturn(vaultsClient);
var keyVaultAccountName = "keyvaultname";
VaultProperties vaultProperties = new VaultProperties();
vaultProperties.withEnableSoftDelete(Boolean.TRUE);
var vault = new VaultInner();
vault.withProperties(vaultProperties);
when(vaultsClient.getByResourceGroup(RESOURCE_GROUP_NAME, keyVaultAccountName)).thenReturn(vault);
steps.retrieveKeyVaultProperties(keyVaultAccountName, RESOURCE_GROUP_NAME, SCOPES, VAR_NAME);
verify(variableContext).putVariable(SCOPES, VAR_NAME,
"{\"properties\":{\"enableSoftDelete\":true}}");
});
}

private void runWithKeyVaultClient(
FailableBiConsumer<KeyVaultManagementClient, KeyVaultManagementSteps, IOException> test) throws IOException
{
try (MockedStatic<KeyVaultManager> keyVaultManagerStaticMock = mockStatic(KeyVaultManager.class))
{
var keyVaultManager = mock(KeyVaultManager.class);
keyVaultManagerStaticMock.when(() -> KeyVaultManager.authenticate(tokenCredential, azureProfile))
.thenReturn(keyVaultManager);
var keyVaultManagementClient = mock(KeyVaultManagementClient.class);
when(keyVaultManager.serviceClient()).thenReturn(keyVaultManagementClient);
var steps = new KeyVaultManagementSteps(azureProfile, tokenCredential, new InnersJacksonAdapter(),
variableContext);
test.accept(keyVaultManagementClient, steps);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-maker-inline
1 change: 1 addition & 0 deletions vividus-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
implementation project(':vividus-plugin-azure-data-factory')
implementation project(':vividus-plugin-azure-event-grid')
implementation project(':vividus-plugin-azure-functions')
implementation project(':vividus-plugin-azure-key-vault')
implementation project(':vividus-plugin-azure-storage-account')
implementation project(':vividus-plugin-azure-storage-queue')
implementation project(':vividus-plugin-browserstack')
Expand Down
2 changes: 1 addition & 1 deletion vividus-tests/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ignoreBeans=dynamoDbSteps,kinesisSteps,lambdaSteps,s3BucketSteps,storageAccountManagementSteps
ignoreBeans=dynamoDbSteps,kinesisSteps,lambdaSteps,s3BucketSteps,storageAccountManagementSteps,keyVaultManagementSteps

0 comments on commit bf93334

Please # to comment.