mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
Add OpenAPI Go and C# (#18896)
* Add OpenAPI Go and C# * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Add code sample links for OpenAPI-based Go and .NET * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> * Remove command flags that are no longer needed * Fix 'OpenAPI C#' > 'OpenAPI .NET' * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> * Update website/content/docs/get-started/developer-qs.mdx Co-authored-by: AnPucel <adiroff@hashicorp.com> --------- Co-authored-by: Anton Averchenkov <84287187+averche@users.noreply.github.com> Co-authored-by: AnPucel <adiroff@hashicorp.com>
This commit is contained in:
@@ -15,6 +15,8 @@ The complete code samples for the steps below are available here:
|
||||
- [C#](https://github.com/hashicorp/vault-examples/blob/main/examples/_quick-start/dotnet/Example.cs)
|
||||
- [Python](https://github.com/hashicorp/vault-examples/blob/main/examples/_quick-start/python/example.py)
|
||||
- [Java (Spring)](https://github.com/hashicorp/vault-examples/blob/main/examples/_quick-start/java/Example.java)
|
||||
- [OpenAPI-based Go](https://github.com/hashicorp/vault-client-go/#getting-started)
|
||||
- [OpenAPI-based .NET](https://github.com/hashicorp/vault-client-dotnet/#getting-started)
|
||||
|
||||
For an out-of-the-box runnable demo application showcasing these concepts and more, see the hello-vault repositories ([Go](https://github.com/hashicorp/hello-vault-go), [C#](https://github.com/hashicorp/hello-vault-dotnet) and [Java/Spring Boot](https://github.com/hashicorp/hello-vault-spring)).
|
||||
|
||||
@@ -57,7 +59,7 @@ Let's install the Vault client library for your language of choice.
|
||||
-> **Note**: Some of these libraries are currently community-maintained.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Go">
|
||||
<Tab heading="Go" group="go">
|
||||
|
||||
[Go](https://pkg.go.dev/github.com/hashicorp/vault/api) (official) client library:
|
||||
|
||||
@@ -76,7 +78,7 @@ import vault "github.com/hashicorp/vault/api"
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Ruby">
|
||||
<Tab heading="Ruby" group="ruby">
|
||||
|
||||
|
||||
[Ruby](https://github.com/hashicorp/vault-ruby) (official) client library:
|
||||
@@ -96,7 +98,7 @@ require "vault"
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="C#">
|
||||
<Tab heading="C#" group="cs">
|
||||
|
||||
|
||||
[C#](https://github.com/rajanadar/VaultSharp) client library:
|
||||
@@ -119,7 +121,7 @@ using VaultSharp.V1.Commons;
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Python">
|
||||
<Tab heading="Python" group="python">
|
||||
|
||||
|
||||
[Python](https://github.com/hvac/hvac) client library:
|
||||
@@ -139,7 +141,7 @@ import hvac
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Java">
|
||||
<Tab heading="Java" group="java">
|
||||
|
||||
|
||||
[Java (Spring)](https://spring.io/projects/spring-vault) client library:
|
||||
@@ -167,6 +169,59 @@ import org.springframework.vault.core.VaultTemplate;
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI Go (Beta)" group="openAPI-go">
|
||||
|
||||
|
||||
[OpenAPI Go](https://github.com/hashicorp/vault-client-go) (Beta) client library:
|
||||
|
||||
```shell-session
|
||||
$ go get github.com/hashicorp/vault-client-go
|
||||
```
|
||||
|
||||
Now, let's add the import statements for the client library to the top of the file.
|
||||
|
||||
<CodeBlockConfig heading="import statements for client library" lineNumbers>
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/hashicorp/vault-client-go"
|
||||
"github.com/hashicorp/vault-client-go/schema"
|
||||
)
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI .NET (Beta)" group="openAPI-dotnet">
|
||||
|
||||
|
||||
[OpenAPI .NET](https://github.com/hashicorp/vault-client-dotnet) (Beta) client library:
|
||||
|
||||
Vault is a package available at [Hashicorp Nuget](https://www.nuget.org/profiles/hashicorp).
|
||||
|
||||
|
||||
```shell-session
|
||||
$ nuget install HashiCorp.Vault -Version "0.1.0-beta"
|
||||
```
|
||||
|
||||
**Or:**
|
||||
|
||||
```shell-session
|
||||
$ dotnet add package Hashicorp.Vault -version "0.1.0-beta"
|
||||
```
|
||||
|
||||
Now, let's add the import statements for the client library to the top of the file.
|
||||
|
||||
<CodeBlockConfig heading="import statements for client library" lineNumbers>
|
||||
|
||||
```cs
|
||||
using Vault;
|
||||
using Vault.Client;
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -179,7 +234,8 @@ A variety of [authentication methods](/vault/docs/auth) can be used to prove you
|
||||
To keep things simple for our example, we'll just use the root token created in **Step 1**.
|
||||
Paste the following code to initialize a new Vault client that will use token-based authentication for all its requests:
|
||||
|
||||
<CodeTabs heading="initialize a new vault client">
|
||||
<Tabs>
|
||||
<Tab heading="Go">
|
||||
|
||||
```go
|
||||
config := vault.DefaultConfig()
|
||||
@@ -194,6 +250,9 @@ if err != nil {
|
||||
client.SetToken("dev-only-token")
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Ruby" group="ruby">
|
||||
|
||||
```ruby
|
||||
Vault.configure do |config|
|
||||
config.address = "http://127.0.0.1:8200"
|
||||
@@ -201,6 +260,9 @@ Vault.configure do |config|
|
||||
end
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="C#" group="cs">
|
||||
|
||||
```cs
|
||||
IAuthMethodInfo authMethod = new TokenAuthMethodInfo(vaultToken: "dev-only-token");
|
||||
|
||||
@@ -209,6 +271,9 @@ VaultClientSettings("http://127.0.0.1:8200", authMethod);
|
||||
IVaultClient vaultClient = new VaultClient(vaultClientSettings);
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Python" group="python">
|
||||
|
||||
```Python
|
||||
client = hvac.Client(
|
||||
url='http://127.0.0.1:8200',
|
||||
@@ -216,6 +281,9 @@ client = hvac.Client(
|
||||
)
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Java" group="java">
|
||||
|
||||
```Java
|
||||
VaultEndpoint vaultEndpoint = new VaultEndpoint();
|
||||
|
||||
@@ -229,11 +297,43 @@ VaultTemplate vaultTemplate = new VaultTemplate(
|
||||
);
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Bash" group="bash">
|
||||
|
||||
```shell-session
|
||||
export VAULT_TOKEN="dev-only-token"
|
||||
$ export VAULT_TOKEN="dev-only-token"
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI Go (Beta)" group="openAPI-go">
|
||||
|
||||
```go
|
||||
client, err := vault.New(
|
||||
vault.WithAddress("http://127.0.0.1:8200"),
|
||||
vault.WithRequestTimeout(30*time.Second),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := client.SetToken("dev-only-token"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI .NET (Beta)" group="openAPI-dotnet">
|
||||
|
||||
```cs
|
||||
string address = "http://127.0.0.1:8200";
|
||||
VaultConfiguration config = new VaultConfiguration(address);
|
||||
|
||||
VaultClient vaultClient = new VaultClient(config);
|
||||
vaultClient.SetToken("dev-only-token");
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Step 4: Store a secret
|
||||
|
||||
@@ -241,7 +341,8 @@ Secrets are sensitive data like API keys and passwords that we shouldn’t be st
|
||||
|
||||
We'll use the Vault client we just initialized to write a secret to Vault, like so:
|
||||
|
||||
<CodeTabs heading="write a secret to vault">
|
||||
<Tabs>
|
||||
<Tab heading="Go">
|
||||
|
||||
```go
|
||||
secretData := map[string]interface{}{
|
||||
@@ -257,6 +358,9 @@ if err != nil {
|
||||
fmt.Println("Secret written successfully.")
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Ruby" group="ruby">
|
||||
|
||||
```ruby
|
||||
secret_data = {data: {password: "Hashi123"}}
|
||||
Vault.logical.write("secret/data/my-secret-password", secret_data)
|
||||
@@ -264,6 +368,9 @@ Vault.logical.write("secret/data/my-secret-password", secret_data)
|
||||
puts "Secret written successfully."
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="C#" group="cs">
|
||||
|
||||
```cs
|
||||
var secretData = new Dictionary<string, object> { { "password", "Hashi123" } };
|
||||
vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(
|
||||
@@ -275,6 +382,9 @@ vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(
|
||||
Console.WriteLine("Secret written successfully.");
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Python" group="python">
|
||||
|
||||
```Python
|
||||
create_response = client.secrets.kv.v2.create_or_update_secret(
|
||||
path='my-secret-password',
|
||||
@@ -284,6 +394,9 @@ create_response = client.secrets.kv.v2.create_or_update_secret(
|
||||
print('Secret written successfully.')
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Java" group="java">
|
||||
|
||||
```Java
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("password", "Hashi123");
|
||||
@@ -295,8 +408,11 @@ Versioned.Metadata createResponse = vaultTemplate
|
||||
System.out.println("Secret written successfully.");
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Bash" group="bash">
|
||||
|
||||
```shell-session
|
||||
curl \
|
||||
$ curl \
|
||||
--header "X-Vault-Token: $VAULT_TOKEN" \
|
||||
--header "Content-Type: application/json" \
|
||||
--request POST \
|
||||
@@ -304,7 +420,36 @@ curl \
|
||||
http://127.0.0.1:8200/v1/secret/data/my-secret-password
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI Go (Beta)" group="openAPI-go">
|
||||
|
||||
```go
|
||||
_, err = client.Secrets.KVv2Write(context.Background(), "my-secret-password", schema.KVv2WriteRequest{
|
||||
Data: map[string]any{
|
||||
"password": "Hashi123",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Secret written successfully.")
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI .NET (Beta)" group="openAPI-dotnet">
|
||||
|
||||
```cs
|
||||
var secretData = new Dictionary<string, string> { { "password", "Hashi123" } };
|
||||
|
||||
// Write a secret
|
||||
var kvRequestData = new KVv2WriteRequest(secretData);
|
||||
|
||||
vaultClient.Secrets.KVv2Write("my-secret-password", kvRequestData);
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
A common way of storing secrets is as key-value pairs using the [KV secrets engine (v2)](/vault/docs/secrets/kv/kv-v2). In the code we've just added, `password` is the key in the key-value pair, and `Hashi123` is the value.
|
||||
|
||||
@@ -318,7 +463,8 @@ Now that we know how to write a secret, let's practice reading one.
|
||||
|
||||
Underneath the line where you wrote a secret to Vault, let's add a few more lines, where we will be retrieving the secret and unpacking the value:
|
||||
|
||||
<CodeTabs heading="read a secret">
|
||||
<Tabs>
|
||||
<Tab heading="Go">
|
||||
|
||||
```go
|
||||
secret, err := client.KVv2("secret").Get(context.Background(), "my-secret-password")
|
||||
@@ -332,11 +478,17 @@ log.Fatalf("value type assertion failed: %T %#v", secret.Data["password"], secre
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Ruby" group="ruby">
|
||||
|
||||
```ruby
|
||||
secret = Vault.logical.read("secret/data/my-secret-password")
|
||||
password = secret.data[:data][:password]
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="C#" group="cs">
|
||||
|
||||
```cs
|
||||
Secret<SecretData> secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(
|
||||
path: "/my-secret-password",
|
||||
@@ -346,12 +498,18 @@ Secret<SecretData> secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(
|
||||
var password = secret.Data.Data["password"];
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Python" group="python">
|
||||
|
||||
```Python
|
||||
read_response = client.secrets.kv.read_secret_version(path='my-secret-password')
|
||||
|
||||
password = read_response['data']['data']['password']
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Java" group="java">
|
||||
|
||||
```Java
|
||||
Versioned<Map<String, Object>> readResponse = vaultTemplate
|
||||
.opsForVersionedKeyValue("secret")
|
||||
@@ -363,17 +521,42 @@ if (readResponse != null && readResponse.hasData()) {
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Bash" group="bash">
|
||||
|
||||
```shell-session
|
||||
curl \
|
||||
$ curl \
|
||||
--header "X-Vault-Token: $VAULT_TOKEN" \
|
||||
http://127.0.0.1:8200/v1/secret/data/my-secret-password > secrets.json
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI Go (Beta)" group="openAPI-go">
|
||||
|
||||
```go
|
||||
s, err := client.Secrets.KVv2Read(context.Background(), "my-secret-password")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Secret retrieved:", s.Data)
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="OpenAPI .NET (Beta)" group="openAPI-dotnet">
|
||||
|
||||
```cs
|
||||
VaultResponse<Object> resp = vaultClient.Secrets.KVv2Read("my-secret-password");
|
||||
Console.WriteLine(resp.Data);
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Last, confirm that the value we unpacked from the read response is correct:
|
||||
|
||||
<CodeTabs heading="confirm value">
|
||||
<Tabs>
|
||||
<Tab heading="Go">
|
||||
|
||||
```go
|
||||
if value != "Hashi123" {
|
||||
@@ -383,12 +566,18 @@ if value != "Hashi123" {
|
||||
fmt.Println("Access granted!")
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Ruby" group="ruby">
|
||||
|
||||
```ruby
|
||||
abort "Unexpected password" if password != "Hashi123"
|
||||
|
||||
puts "Access granted!"
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="C#" group="cs">
|
||||
|
||||
```cs
|
||||
if (password.ToString() != "Hashi123")
|
||||
{
|
||||
@@ -398,6 +587,9 @@ if (password.ToString() != "Hashi123")
|
||||
Console.WriteLine("Access granted!");
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Python" group="python">
|
||||
|
||||
```Python
|
||||
if password != 'Hashi123':
|
||||
sys.exit('unexpected password')
|
||||
@@ -405,6 +597,9 @@ if password != 'Hashi123':
|
||||
print('Access granted!')
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Java" group="java">
|
||||
|
||||
```Java
|
||||
if (!password.equals("Hashi123")) {
|
||||
throw new Exception("Unexpected password");
|
||||
@@ -413,10 +608,15 @@ if (!password.equals("Hashi123")) {
|
||||
System.out.println("Access granted!");
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Bash" group="bash">
|
||||
|
||||
```shell-session
|
||||
cat secrets.json | jq '.data.data'
|
||||
$ cat secrets.json | jq '.data.data'
|
||||
```
|
||||
</CodeTabs>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
If the secret was fetched successfully, you should see the `Access granted!` message after you run the code. If not, check to see if you provided the correct path to your secret.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user