github.com/angryronald/go-kit@v0.0.0-20240505173814-ff2bd9c79dbf/test/docker/vault/vault.dockertest.go (about)

     1  package vault
     2  
     3  /*
     4  There is an issue with dockertest which seems to be able to pull the image and spin it up, but it turns out the container never created
     5  */
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"net/http"
    11  	"time"
    12  
    13  	"github.com/hashicorp/vault/api"
    14  	"github.com/ory/dockertest/v3"
    15  )
    16  
    17  const vaultTestRootToken = "701432d1-00e7-7c94-10c4-8450ab3c4b31"
    18  
    19  func GenerateInstance(pool *dockertest.Pool, data map[string]interface{}) (*api.Client, *dockertest.Resource, *api.Secret) {
    20  	// Set up options for Vault container
    21  	options := &dockertest.RunOptions{
    22  		Repository: "docker.io/hashicorp/vault",
    23  		Tag:        "latest",
    24  		Name:       "vault-container",
    25  		Cmd:        []string{"vault", "server", "-dev", "-dev-root-token-id", vaultTestRootToken, "-dev-listen-address", "0.0.0.0:8200"},
    26  	}
    27  
    28  	// Run Vault container
    29  	resource, err := pool.RunWithOptions(options)
    30  	if err != nil {
    31  		log.Fatalf("Could not start Vault container: %s", err)
    32  	}
    33  
    34  	if err := pool.Retry(func() error {
    35  		// Your logic to check if the container is ready
    36  		// This can be connecting to a port, checking logs, etc.
    37  
    38  		// Example: Check if Vault is responsive on the specified port
    39  		port := resource.GetPort("8200/tcp")
    40  		if port == "" {
    41  			return fmt.Errorf("container does not expose port 8200/tcp")
    42  		}
    43  
    44  		vaultURL := fmt.Sprintf("http://localhost:%s", port)
    45  		resp, err := http.Get(vaultURL)
    46  		if err != nil {
    47  			return fmt.Errorf("error making HTTP request to Vault: %v", err)
    48  		}
    49  		defer resp.Body.Close()
    50  
    51  		if resp.StatusCode != http.StatusOK {
    52  			return fmt.Errorf("Vault is not responsive, status code: %d", resp.StatusCode)
    53  		}
    54  
    55  		return nil
    56  	}); err != nil {
    57  		if err := pool.Purge(resource); err != nil {
    58  			log.Fatalf("Could not purge vault resource: %s\n", err)
    59  		}
    60  		log.Fatalf("Could not connect to Docker: %v", err)
    61  	}
    62  
    63  	// At this point, Vault should be running and ready to use.
    64  	client, err := api.NewClient(&api.Config{
    65  		Address: "http://127.0.0.1:8200/v1/kv/",
    66  		HttpClient: &http.Client{
    67  			Timeout: 10 * time.Second,
    68  		},
    69  	})
    70  	if err != nil {
    71  		if err := pool.Purge(resource); err != nil {
    72  			log.Fatalf("Could not purge vault resource: %s\n", err)
    73  		}
    74  		log.Fatalf("Unable to create vault client: %v", err)
    75  	}
    76  
    77  	client.SetToken(vaultTestRootToken)
    78  
    79  	newdata := make(map[string]interface{})
    80  	newdata["data"] = data
    81  	_, err = client.Logical().Write("secret/data/test", newdata)
    82  	if err != nil {
    83  		if err := pool.Purge(resource); err != nil {
    84  			log.Fatalf("Could not purge vault resource: %s\n", err)
    85  		}
    86  		log.Fatalf("Unable to write test value to vault: %v", err)
    87  	}
    88  
    89  	secret, err := client.Logical().Read("secret/data/test")
    90  	if err != nil {
    91  		if err := pool.Purge(resource); err != nil {
    92  			log.Fatalf("Could not purge vault resource: %s\n", err)
    93  		}
    94  		log.Fatalf("Unable to read test value from vault: %v", err)
    95  	}
    96  
    97  	return client, resource, secret
    98  }