generated from oracle/template-repo
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Anders Swanson <[email protected]>
- Loading branch information
1 parent
72c7c03
commit ec35da5
Showing
12 changed files
with
423 additions
and
2 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
...oci-autoconfigure/src/main/java/com/oracle/cloud/spring/vault/VaultAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
** 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 | ||
@ConditionalOnProperty(name = "spring.cloud.oci.genai.embedding.enabled", havingValue = "true", matchIfMissing = true) | ||
@ConditionalOnMissingBean(Vault.class) | ||
public Vault embeddingModel(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; | ||
} | ||
} | ||
|
27 changes: 27 additions & 0 deletions
27
...-cloud-oci-autoconfigure/src/main/java/com/oracle/cloud/spring/vault/VaultProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletion
6
...SpringCloudOciVaultSampleApplication.java → ...SpringCloudOciVaultSampleApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
.../java/com/oracle/cloud/spring/sample/vault/springcloudocivaultsample/VaultController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
** 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)); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...cloud-oci-samples/spring-cloud-oci-vault-sample/src/main/resources/application.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
56 changes: 56 additions & 0 deletions
56
...src/test/java/com/oracle/cloud/spring/sample/vault/springcloudocivaultsample/VaultIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
** 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.UUID; | ||
|
||
import com.oracle.bmc.secrets.responses.GetSecretBundleByNameResponse; | ||
import com.oracle.bmc.vault.model.Base64SecretContentDetails; | ||
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.Disabled; | ||
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 | ||
@Disabled | ||
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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
spring-cloud-oci-vault/src/main/java/com/oracle/cloud/spring/vault/Vault.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,35 @@ | ||
/* | ||
** 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 java.nio.charset.StandardCharsets; | ||
import java.util.Base64; | ||
import java.util.Date; | ||
|
||
import com.oracle.bmc.secrets.model.Base64SecretBundleContentDetails; | ||
import com.oracle.bmc.secrets.model.SecretBundleContentDetails; | ||
import com.oracle.bmc.secrets.responses.GetSecretBundleByNameResponse; | ||
import com.oracle.bmc.vault.model.CreateSecretDetails; | ||
import com.oracle.bmc.vault.model.UpdateSecretDetails; | ||
import com.oracle.bmc.vault.responses.CreateSecretResponse; | ||
import com.oracle.bmc.vault.responses.ScheduleSecretDeletionResponse; | ||
import com.oracle.bmc.vault.responses.UpdateSecretResponse; | ||
|
||
public interface Vault { | ||
GetSecretBundleByNameResponse getSecret(String secretName); | ||
CreateSecretResponse createSecret(String secretName, CreateSecretDetails body); | ||
ScheduleSecretDeletionResponse scheduleSecretDeletion(String secretName, Date timeOfDeletion); | ||
UpdateSecretResponse updateSecret(String secretName, UpdateSecretDetails body); | ||
|
||
default String decodeBundle(GetSecretBundleByNameResponse bundle) { | ||
SecretBundleContentDetails content = bundle.getSecretBundle().getSecretBundleContent(); | ||
if (content instanceof Base64SecretBundleContentDetails) { | ||
Base64SecretBundleContentDetails encoded = (Base64SecretBundleContentDetails) content; | ||
return new String(Base64.getDecoder().decode(encoded.getContent()), StandardCharsets.UTF_8); | ||
} else { | ||
return content.toString(); | ||
} | ||
} | ||
} |
89 changes: 88 additions & 1 deletion
89
spring-cloud-oci-vault/src/main/java/com/oracle/cloud/spring/vault/VaultImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,91 @@ | ||
/* | ||
** 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; | ||
|
||
public class VaultImpl { | ||
import java.util.Date; | ||
|
||
import com.oracle.bmc.secrets.Secrets; | ||
import com.oracle.bmc.secrets.requests.GetSecretBundleByNameRequest; | ||
import com.oracle.bmc.secrets.responses.GetSecretBundleByNameResponse; | ||
import com.oracle.bmc.vault.Vaults; | ||
import com.oracle.bmc.vault.model.CreateSecretDetails; | ||
import com.oracle.bmc.vault.model.ScheduleSecretDeletionDetails; | ||
import com.oracle.bmc.vault.model.UpdateSecretDetails; | ||
import com.oracle.bmc.vault.requests.CreateSecretRequest; | ||
import com.oracle.bmc.vault.requests.ScheduleSecretDeletionRequest; | ||
import com.oracle.bmc.vault.requests.UpdateSecretRequest; | ||
import com.oracle.bmc.vault.responses.CreateSecretResponse; | ||
import com.oracle.bmc.vault.responses.ScheduleSecretDeletionResponse; | ||
import com.oracle.bmc.vault.responses.UpdateSecretResponse; | ||
import org.springframework.util.Assert; | ||
|
||
public class VaultImpl implements Vault { | ||
private final Vaults vaults; | ||
private final Secrets secrets; | ||
private final String vaultId; | ||
private final String compartmentId; | ||
|
||
public VaultImpl(Vaults vaults, Secrets secrets, String vaultId, String compartmentId) { | ||
Assert.notNull(vaults, "vaults must not be null"); | ||
Assert.notNull(secrets, "secrets must not be null"); | ||
Assert.hasText(vaultId, "vaultId must not be empty"); | ||
Assert.hasText(compartmentId, "compartmentId must not be empty"); | ||
this.vaults = vaults; | ||
this.secrets = secrets; | ||
this.vaultId = vaultId; | ||
this.compartmentId = compartmentId; | ||
} | ||
|
||
public GetSecretBundleByNameResponse getSecret(String secretName) { | ||
Assert.hasText(secretName, "secretName must not be empty"); | ||
GetSecretBundleByNameRequest request = GetSecretBundleByNameRequest.builder() | ||
.vaultId(vaultId) | ||
.secretName(secretName) | ||
.build(); | ||
return secrets.getSecretBundleByName(request); | ||
} | ||
|
||
public CreateSecretResponse createSecret(String secretName, CreateSecretDetails body) { | ||
Assert.hasText(secretName, "secretName must not be empty"); | ||
Assert.notNull(body, "body must not be null"); | ||
CreateSecretRequest request = CreateSecretRequest.builder() | ||
.body$(body.toBuilder() | ||
.vaultId(vaultId) | ||
.compartmentId(compartmentId) | ||
.secretName(secretName) | ||
.build()) | ||
.build(); | ||
return vaults.createSecret(request); | ||
} | ||
|
||
public ScheduleSecretDeletionResponse scheduleSecretDeletion(String secretName, Date timeOfDeletion) { | ||
Assert.hasText(secretName, "secretName must not be empty"); | ||
Assert.notNull(timeOfDeletion, "timeOfDeletion must not be null"); | ||
String secretId = getSecret(secretName) | ||
.getSecretBundle() | ||
.getSecretId(); | ||
ScheduleSecretDeletionDetails body = ScheduleSecretDeletionDetails.builder() | ||
.timeOfDeletion(timeOfDeletion) | ||
.build(); | ||
ScheduleSecretDeletionRequest request = ScheduleSecretDeletionRequest.builder() | ||
.secretId(secretId) | ||
.body$(body) | ||
.build(); | ||
return vaults.scheduleSecretDeletion(request); | ||
} | ||
|
||
public UpdateSecretResponse updateSecret(String secretName, UpdateSecretDetails body) { | ||
Assert.hasText(secretName, "secretName must not be empty"); | ||
Assert.notNull(body, "body must not be null"); | ||
String secretId = getSecret(secretName) | ||
.getSecretBundle() | ||
.getSecretId(); | ||
UpdateSecretRequest request = UpdateSecretRequest.builder() | ||
.secretId(secretId) | ||
.body$(body) | ||
.build(); | ||
return vaults.updateSecret(request); | ||
} | ||
} |
Oops, something went wrong.