provider/vault: vault_generic_secret data source
This commit is contained in:
parent
c1d1f902f5
commit
25f73dac83
|
@ -0,0 +1,106 @@
|
|||
package vault
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
)
|
||||
|
||||
func genericSecretDataSource() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: genericSecretDataSourceRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"path": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Full path from which a secret will be read.",
|
||||
},
|
||||
|
||||
"data_json": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "JSON-encoded secret data read from Vault.",
|
||||
},
|
||||
|
||||
"data": &schema.Schema{
|
||||
Type: schema.TypeMap,
|
||||
Computed: true,
|
||||
Description: "Map of strings read from Vault.",
|
||||
},
|
||||
|
||||
"lease_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Lease identifier assigned by vault.",
|
||||
},
|
||||
|
||||
"lease_duration": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Lease duration in seconds relative to the time in lease_start_time.",
|
||||
},
|
||||
|
||||
"lease_start_time": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Time at which the lease was read, using the clock of the system where Terraform was running",
|
||||
},
|
||||
|
||||
"lease_renewable": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "True if the duration of this lease can be extended through renewal.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func genericSecretDataSourceRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*api.Client)
|
||||
|
||||
path := d.Get("path").(string)
|
||||
|
||||
log.Printf("[DEBUG] Reading %s from Vault", path)
|
||||
secret, err := client.Logical().Read(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading from Vault: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(secret.RequestID)
|
||||
|
||||
// Ignoring error because this value came from JSON in the
|
||||
// first place so no reason why it should fail to re-encode.
|
||||
jsonDataBytes, _ := json.Marshal(secret.Data)
|
||||
d.Set("data_json", string(jsonDataBytes))
|
||||
|
||||
// Since our "data" map can only contain string values, we
|
||||
// will take strings from Data and write them in as-is,
|
||||
// and write everything else in as a JSON serialization of
|
||||
// whatever value we get so that complex types can be
|
||||
// passed around and processed elsewhere if desired.
|
||||
dataMap := map[string]string{}
|
||||
for k, v := range secret.Data {
|
||||
if vs, ok := v.(string); ok {
|
||||
dataMap[k] = vs
|
||||
} else {
|
||||
// Again ignoring error because we know this value
|
||||
// came from JSON in the first place and so must be valid.
|
||||
vBytes, _ := json.Marshal(v)
|
||||
dataMap[k] = string(vBytes)
|
||||
}
|
||||
}
|
||||
d.Set("data", dataMap)
|
||||
|
||||
d.Set("lease_id", secret.LeaseID)
|
||||
d.Set("lease_duration", secret.LeaseDuration)
|
||||
d.Set("lease_start_time", time.Now().Format("RFC3339"))
|
||||
d.Set("lease_renewable", secret.Renewable)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package vault
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
r "github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestDataSourceGenericSecret(t *testing.T) {
|
||||
r.Test(t, r.TestCase{
|
||||
Providers: testProviders,
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Steps: []r.TestStep{
|
||||
r.TestStep{
|
||||
Config: testDataSourceGenericSecret_config,
|
||||
Check: testDataSourceGenericSecret_check,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
var testDataSourceGenericSecret_config = `
|
||||
|
||||
resource "vault_generic_secret" "test" {
|
||||
path = "secret/foo"
|
||||
data_json = <<EOT
|
||||
{
|
||||
"zip": "zap"
|
||||
}
|
||||
EOT
|
||||
}
|
||||
|
||||
data "vault_generic_secret" "test" {
|
||||
path = "${vault_generic_secret.test.path}"
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
func testDataSourceGenericSecret_check(s *terraform.State) error {
|
||||
resourceState := s.Modules[0].Resources["data.vault_generic_secret.test"]
|
||||
if resourceState == nil {
|
||||
return fmt.Errorf("resource not found in state %v", s.Modules[0].Resources)
|
||||
}
|
||||
|
||||
iState := resourceState.Primary
|
||||
if iState == nil {
|
||||
return fmt.Errorf("resource has no primary instance")
|
||||
}
|
||||
|
||||
wantJson := `{"zip":"zap"}`
|
||||
if got, want := iState.Attributes["data_json"], wantJson; got != want {
|
||||
return fmt.Errorf("data_json contains %s; want %s", got, want)
|
||||
}
|
||||
|
||||
if got, want := iState.Attributes["data.zip"], "zap"; got != want {
|
||||
return fmt.Errorf("data[\"zip\"] contains %s; want %s", got, want)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -82,6 +82,10 @@ func Provider() terraform.ResourceProvider {
|
|||
|
||||
ConfigureFunc: providerConfigure,
|
||||
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"vault_generic_secret": genericSecretDataSource(),
|
||||
},
|
||||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"vault_generic_secret": genericSecretResource(),
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue