Skip to content

OCI Vault #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Licensed under the Universal Permissive License v 1.0 as shown at https://oss.or
<module>spring-cloud-oci-logging</module>
<module>spring-cloud-oci-function</module>
<module>spring-cloud-oci-streaming</module>
<module>spring-cloud-oci-vault</module>
<module>spring-cloud-oci-queue</module>
<module>docs</module>
</modules>
Expand Down
5 changes: 5 additions & 0 deletions spring-cloud-oci-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ Licensed under the Universal Permissive License v 1.0 as shown at https://oss.or
<artifactId>spring-cloud-oci-streaming</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-vault</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-queue</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2024, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
package com.oracle.cloud.spring.vault;


import com.oracle.bmc.auth.RegionProvider;
import com.oracle.bmc.secrets.Secrets;
import com.oracle.bmc.secrets.SecretsClient;
import com.oracle.bmc.vault.Vaults;
import com.oracle.bmc.vault.VaultsClient;
import com.oracle.cloud.spring.autoconfigure.core.CredentialsProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;

import static com.oracle.cloud.spring.autoconfigure.core.CredentialsProviderAutoConfiguration.credentialsProviderQualifier;
import static com.oracle.cloud.spring.autoconfigure.core.RegionProviderAutoConfiguration.regionProviderQualifier;

/**
* Auto-configuration for initializing the OCI Vault component.
* Depends on {@link com.oracle.cloud.spring.autoconfigure.core.CredentialsProviderAutoConfiguration} and
* {@link com.oracle.cloud.spring.autoconfigure.core.RegionProviderAutoConfiguration}
* for loading the Authentication configuration
*
* @see Vault
*/
@AutoConfiguration
@ConditionalOnClass({Vault.class})
@EnableConfigurationProperties(VaultProperties.class)
@ConditionalOnProperty(name = "spring.cloud.oci.vault.enabled", havingValue = "true", matchIfMissing = true)
public class VaultAutoConfiguration {
private final VaultProperties properties;

public VaultAutoConfiguration(VaultProperties properties) {
this.properties = properties;
}

@Bean
@RefreshScope
@ConditionalOnMissingBean(Vault.class)
public Vault vault(Vaults vaults, Secrets secrets) {
return new VaultImpl(vaults, secrets, properties.getVaultId(), properties.getCompartment());
}

@Bean
@RefreshScope
@ConditionalOnMissingBean
public Vaults vaults(@Qualifier(regionProviderQualifier) RegionProvider regionProvider,
@Qualifier(credentialsProviderQualifier)
CredentialsProvider cp) {
Vaults vaults = VaultsClient.builder()
.build(cp.getAuthenticationDetailsProvider());
if (regionProvider.getRegion() != null) {
vaults.setRegion(regionProvider.getRegion());
}
return vaults;
}

@Bean
@RefreshScope
@ConditionalOnMissingBean
public Secrets secrets(@Qualifier(regionProviderQualifier) RegionProvider regionProvider,
@Qualifier(credentialsProviderQualifier)
CredentialsProvider cp) {
Secrets secrets = SecretsClient.builder()
.build(cp.getAuthenticationDetailsProvider());
if (regionProvider.getRegion() != null) {
secrets.setRegion(regionProvider.getRegion());
}
return secrets;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2024, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
package com.oracle.cloud.spring.vault;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = VaultProperties.PREFIX)
public class VaultProperties {
public static final String PREFIX = "spring.cloud.oci.vault";

private String compartment;
private String vaultId;

public String getCompartment() {
return compartment;
}

public void setCompartment(String compartment) {
this.compartment = compartment;
}

public String getVaultId() {
return vaultId;
}

public void setVaultId(String vaultId) {
this.vaultId = vaultId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
"description": "Auto-configure OCI Cloud streaming components.",
"defaultValue": true
},
{
"name": "spring.cloud.oci.vault.enabled",
"type": "java.lang.Boolean",
"description": "Auto-configure OCI Cloud vault components.",
"defaultValue": true
},
{
"name": "spring.cloud.oci.queue.enabled",
"type": "java.lang.Boolean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ com.oracle.cloud.spring.function.FunctionAutoConfiguration
com.oracle.cloud.spring.streaming.StreamingAutoConfiguration
com.oracle.cloud.spring.queue.QueueAutoConfiguration
com.oracle.cloud.spring.genai.GenAIAutoConfiguration
com.oracle.cloud.spring.vault.VaultAutoConfiguration
10 changes: 10 additions & 0 deletions spring-cloud-oci-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
<artifactId>spring-cloud-oci-storage</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-vault</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-function</artifactId>
Expand Down Expand Up @@ -105,6 +110,11 @@
<artifactId>spring-cloud-oci-starter-streaming</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-starter-vault</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-starter-storage</artifactId>
Expand Down
1 change: 1 addition & 0 deletions spring-cloud-oci-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Licensed under the Universal Permissive License v 1.0 as shown at https://oss.or
<module>spring-cloud-oci-gen-ai-sample</module>
<module>spring-cloud-oci-logging-sample</module>
<module>spring-cloud-oci-streaming-sample</module>
<module>spring-cloud-oci-vault-sample</module>
<module>spring-cloud-oci-queue-sample</module>
<module>spring-cloud-oci-function-sample</module>
</modules>
Expand Down
55 changes: 55 additions & 0 deletions spring-cloud-oci-samples/spring-cloud-oci-vault-sample/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2024, Oracle and/or its affiliates.
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-samples</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.oracle.cloud.spring.sample.genai</groupId>
<artifactId>spring-cloud-oci-vault-sample</artifactId>
<name>spring-cloud-oci-vault-sample</name>
<description>spring-cloud-oci-vault-sample</description>
<licenses>
<license>
<name>The Universal Permissive License (UPL), Version 1.0</name>
<url>https://oss.oracle.com/licenses/upl/</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.oracle.cloud.spring</groupId>
<artifactId>spring-cloud-oci-starter-vault</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring.sample.common</groupId>
<artifactId>spring-cloud-oci-common-samples-utils</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.cloud.spring.sample.common</groupId>
<artifactId>spring-cloud-oci-common-samples-utils</artifactId>
<type>test-jar</type>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2024, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
package com.oracle.cloud.spring.sample.vault.springcloudocivaultsample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringCloudOciVaultSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudOciVaultSampleApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2024, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
package com.oracle.cloud.spring.sample.vault.springcloudocivaultsample;

import com.oracle.bmc.secrets.responses.GetSecretBundleByNameResponse;
import com.oracle.cloud.spring.vault.Vault;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demoapp/api/vault/")
@Tag(name = "streaming APIs")
public class VaultController {
private final Vault vault;

public VaultController(Vault vault) {
this.vault = vault;
}

@GetMapping("secret")
public ResponseEntity<?> getSecret(@RequestParam String secretName) {
GetSecretBundleByNameResponse secret = vault.getSecret(secretName);
return ResponseEntity.ok(vault.decodeBundle(secret));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024, Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/

spring.cloud.oci.region.static=us-chicago-1
spring.cloud.oci.config.type=file

spring.cloud.oci.vault.compartment=${OCI_COMPARTMENT_ID}
spring.cloud.oci.vault.vault-id=${OCI_VAULT_ID}
spring.cloud.oci.vault.enabled=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2024, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
package com.oracle.cloud.spring.sample.vault.springcloudocivaultsample;

import java.util.Base64;
import java.util.List;
import java.util.UUID;

import com.oracle.bmc.secrets.responses.GetSecretBundleByNameResponse;
import com.oracle.bmc.vault.model.Base64SecretContentDetails;
import com.oracle.bmc.vault.model.SecretSummary;
import com.oracle.bmc.vault.model.UpdateSecretDetails;
import com.oracle.bmc.vault.responses.UpdateSecretResponse;
import com.oracle.cloud.spring.vault.Vault;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Requires an existing vault, identified by the OCI_VAULT_ID environment variable.
*/
@SpringBootTest
@EnabledIfEnvironmentVariable(named = "OCI_COMPARTMENT_ID", matches = ".+")
@EnabledIfEnvironmentVariable(named = "OCI_VAULT_ID", matches = ".+")
public class VaultIT {
@Autowired
Vault vault;

private final String secretName = "mysecret";

@Test
void getSecret() {
GetSecretBundleByNameResponse secret = vault.getSecret(secretName);
String decoded = vault.decodeBundle(secret);
assertThat(decoded).isNotNull();
assertThat(decoded).hasSizeGreaterThan(1);
}

@Test
void updateSecret() {
String content = UUID.randomUUID().toString();
Base64SecretContentDetails contentDetails = Base64SecretContentDetails.builder()
.content(Base64.getEncoder().encodeToString(content.getBytes()))
.name(content)
.build();
UpdateSecretResponse response = vault.updateSecret(secretName, UpdateSecretDetails.builder()
.secretContent(contentDetails)
.build());
assertThat(response.getSecret()).isNotNull();
}

@Test
void listSecret() {
List<SecretSummary> summaries = vault.listSecrets();
assertThat(summaries).hasSize(1);
}
}
1 change: 1 addition & 0 deletions spring-cloud-oci-starters/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Licensed under the Universal Permissive License v 1.0 as shown at https://oss.or
<module>spring-cloud-oci-starter-gen-ai</module>
<module>spring-cloud-oci-starter-logging</module>
<module>spring-cloud-oci-starter-streaming</module>
<module>spring-cloud-oci-starter-vault</module>
<module>spring-cloud-oci-starter-queue</module>
<module>spring-cloud-oci-starter-function</module>
</modules>
Expand Down
Loading
Loading