Skip to content

Commit

Permalink
test: add tests for github, k8s and iam auth types
Browse files Browse the repository at this point in the history
  • Loading branch information
werne2j committed Aug 26, 2021
1 parent a47fcae commit 830266c
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 46 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
func NewRootCommand() *cobra.Command {
var command = &cobra.Command{
Use: "argocd-vault-plugin",
Short: "This is a plugin to replace <wildcards> with Vault secrets",
Short: "This is a plugin to replace <placeholders> with Vault secrets",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
Expand Down
2 changes: 1 addition & 1 deletion docs/cmd/avp.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This is a plugin to replace <wildcards\> with Vault secrets
This is a plugin to replace <placeholder\>'s with Vault secrets

```
argocd-vault-plugin [flags]
Expand Down
16 changes: 7 additions & 9 deletions pkg/auth/ibmsecretsmanager/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@ import (
"net/http"
"net/url"
"strings"
"time"

"github.com/IBM/argocd-vault-plugin/pkg/types"
"github.com/IBM/argocd-vault-plugin/pkg/utils"
"github.com/hashicorp/vault/api"
)

// IAMAuth is a struct for working with SecretManager that uses IAM
type IAMAuth struct {
APIKey string
Client types.HTTPClient
}

// NewIAMAuth initializes a new IAMAuth with api key
func NewIAMAuth(apikey string) *IAMAuth {
func NewIAMAuth(apikey string, client types.HTTPClient) *IAMAuth {
iamAuth := &IAMAuth{
APIKey: apikey,
Client: client,
}

return iamAuth
}

// Authenticate authenticates with Vault using App Role and returns a token
func (i *IAMAuth) Authenticate(vaultClient *api.Client) error {
accessToken, err := getAccessToken(i.APIKey)
accessToken, err := getAccessToken(i.APIKey, i.Client)
if err != nil {
return err
}
Expand All @@ -52,7 +54,7 @@ func (i *IAMAuth) Authenticate(vaultClient *api.Client) error {
return nil
}

func getAccessToken(apikey string) (string, error) {
func getAccessToken(apikey string, client types.HTTPClient) (string, error) {
// Set url values to be added to the request
urlValues := url.Values{}
urlValues.Set("grant_type", "urn:ibm:params:oauth:grant-type:apikey")
Expand All @@ -66,12 +68,8 @@ func getAccessToken(apikey string) (string, error) {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "application/json")

var httpClient = &http.Client{
Timeout: 10 * time.Second,
}

// Perform http request
res, err := httpClient.Do(req)
res, err := client.Do(req)
if err != nil {
return "", err
}
Expand Down
39 changes: 39 additions & 0 deletions pkg/auth/ibmsecretsmanager/iam_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
package ibmsecretsmanager_test

import (
"bytes"
"io/ioutil"
"net/http"
"testing"

"github.com/IBM/argocd-vault-plugin/pkg/auth/ibmsecretsmanager"
"github.com/IBM/argocd-vault-plugin/pkg/helpers"
)

// MockClient is the mock client
type MockClient struct{}

// Do is the mock client's `Do` func
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
json := `{"access_token":"123"}`

// create a new reader with that JSON
r := ioutil.NopCloser(bytes.NewReader([]byte(json)))
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
}

// Need to find a way to mock GitHub Auth within Vault
func TestIBMAuth(t *testing.T) {
cluster := helpers.CreateTestAuthVault(t)
defer cluster.Cleanup()

c := &MockClient{}
ibm := ibmsecretsmanager.NewIAMAuth("abc", c)

err := ibm.Authenticate(cluster.Cores[0].Client)
if err != nil {
t.Fatalf("expected no errors but got: %s", err)
}
}
1 change: 0 additions & 1 deletion pkg/auth/vault/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ func (g *GithubAuth) Authenticate(vaultClient *api.Client) error {
if err != nil {
return err
}

// If we cannot write the Vault token, we'll just have to login next time. Nothing showstopping.
err = utils.SetToken(vaultClient, data.Auth.ClientToken)
if err != nil {
Expand Down
31 changes: 18 additions & 13 deletions pkg/auth/vault/github_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package vault_test

import (
"testing"

"github.com/IBM/argocd-vault-plugin/pkg/auth/vault"
"github.com/IBM/argocd-vault-plugin/pkg/helpers"
)

// Need to find a way to mock GitHub Auth within Vault
// func TestGithubLogin(t *testing.T) {
// cluster, role, secret := helpers.CreateTestVault(t)
// defer cluster.Cleanup()
//
// github := auth.Github{
// AccessToken: "test",
// }
//
// err := github.Authenticate(cluster.Cores[0].Client)
// if err != nil {
// t.Fatalf("expected no errors but got: %s", err)
// }
// }
func TestGithubLogin(t *testing.T) {
cluster := helpers.CreateTestAuthVault(t)
defer cluster.Cleanup()

github := vault.NewGithubAuth("123")

err := github.Authenticate(cluster.Cores[0].Client)
if err != nil {
t.Fatalf("expected no errors but got: %s", err)
}
}
69 changes: 57 additions & 12 deletions pkg/auth/vault/kubernetes_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
package vault_test

// Need to find a way to mock k8s Auth within Vault
// func TestGithubLogin(t *testing.T) {
// cluster, role, secret := helpers.CreateTestVault(t)
// defer cluster.Cleanup()
//
// k8s := vault.NewK8sAuth("", "", "")
//
// err := k8s.Authenticate(cluster.Cores[0].Client)
// if err != nil {
// t.Fatalf("expected no errors but got: %s", err)
// }
// }
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/IBM/argocd-vault-plugin/pkg/auth/vault"
"github.com/IBM/argocd-vault-plugin/pkg/helpers"
)

const saPath = "/tmp/avp/kubernetes.io/serviceaccount"

func writeK8sToken() error {
err := os.MkdirAll(saPath, os.ModePerm)
if err != nil {
return fmt.Errorf("Could not create directory: %s", err.Error())
}

data := []byte("123456")
err = ioutil.WriteFile(filepath.Join(saPath, "token"), data, 0644)
if err != nil {
return err
}
return nil
}

func removeK8sToken() error {
err := os.RemoveAll("/tmp/avp")
if err != nil {
return err
}
return nil
}

// Need to find a way to mock GitHub Auth within Vault
func TestKubernetesAuth(t *testing.T) {
cluster := helpers.CreateTestAuthVault(t)
defer cluster.Cleanup()

err := writeK8sToken()
if err != nil {
t.Fatalf("error writing token: %s", err)
}

k8s := vault.NewK8sAuth("role", "", string(filepath.Join(saPath, "token")))

err = k8s.Authenticate(cluster.Cores[0].Client)
if err != nil {
t.Fatalf("expected no errors but got: %s", err)
}

err = removeK8sToken()
if err != nil {
fmt.Println(err)
}
}
22 changes: 14 additions & 8 deletions pkg/backends/ibmsecretsmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@ package backends_test

import (
"fmt"
"net/http"
"reflect"
"testing"

"github.com/IBM/argocd-vault-plugin/pkg/auth/ibmsecretsmanager"
"github.com/IBM/argocd-vault-plugin/pkg/backends"
"github.com/IBM/argocd-vault-plugin/pkg/helpers"
)

// MockClient is the mock client
type MockClient struct{}

// Do is the mock client's `Do` func
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
return &http.Response{}, nil
}

func TestSecretsManagerGetSecrets(t *testing.T) {
ln, client, _ := helpers.CreateTestVault(t)
defer ln.Close()

sm := backends.IBMSecretsManager{
IBMCloudAPIKey: "token",
VaultClient: client,
}
iamAuth := ibmsecretsmanager.NewIAMAuth("token", &MockClient{})
sm := backends.NewIBMSecretsManagerBackend(iamAuth, client)

expected := map[string]interface{}{
"secret": "value",
Expand All @@ -37,10 +45,8 @@ func TestSecretsmanagerGetSecretsFail(t *testing.T) {
ln, client, _ := helpers.CreateTestVault(t)
defer ln.Close()

sm := backends.IBMSecretsManager{
IBMCloudAPIKey: "token",
VaultClient: client,
}
iamAuth := ibmsecretsmanager.NewIAMAuth("token", &MockClient{})
sm := backends.NewIBMSecretsManagerBackend(iamAuth, client)

_, err := sm.GetSecrets("secret/ibm/arbitrary/groups/3", map[string]string{})

Expand Down
3 changes: 2 additions & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/IBM/argocd-vault-plugin/pkg/backends"
"github.com/IBM/argocd-vault-plugin/pkg/kube"
"github.com/IBM/argocd-vault-plugin/pkg/types"
"github.com/IBM/argocd-vault-plugin/pkg/utils"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
Expand Down Expand Up @@ -100,7 +101,7 @@ func New(v *viper.Viper, co *Options) (*Config, error) {
switch authType {
case types.IAMAuth:
if v.IsSet(types.EnvAvpIBMAPIKey) {
auth = ibmsecretsmanager.NewIAMAuth(v.GetString(types.EnvAvpIBMAPIKey))
auth = ibmsecretsmanager.NewIAMAuth(v.GetString(types.EnvAvpIBMAPIKey), utils.DefaultHttpClient())
} else {
return nil, fmt.Errorf("%s for iam authentication cannot be empty", types.EnvAvpIBMAPIKey)
}
Expand Down
50 changes: 50 additions & 0 deletions pkg/helpers/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,56 @@ func CreateTestAppRoleVault(t *testing.T) (*vault.TestCluster, string, string) {
return cluster, roleID, secretID
}

// CreateTestGithubVault initializes a new test vault with AppRole and Kv v2
func CreateTestAuthVault(t *testing.T) *vault.TestCluster {
t.Helper()

coreConfig := &vault.CoreConfig{
CredentialBackends: map[string]logical.Factory{
"github": Factory,
"kubernetes": Factory,
"ibmcloud": Factory,
},
}

cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
HandlerFunc: http.Handler,
})

cluster.Start()

vault.TestWaitActive(t, cluster.Cores[0].Core)

client := cluster.Cores[0].Client

client.Sys().Mount("kv", &api.MountInput{
Type: "kv",
Options: map[string]string{
"version": "2",
},
})

if err := client.Sys().EnableAuthWithOptions("github", &api.EnableAuthOptions{
Type: "github",
}); err != nil {
t.Fatal(err)
}

if err := client.Sys().EnableAuthWithOptions("kubernetes", &api.EnableAuthOptions{
Type: "kubernetes",
}); err != nil {
t.Fatal(err)
}

if err := client.Sys().EnableAuthWithOptions("ibmcloud", &api.EnableAuthOptions{
Type: "ibmcloud",
}); err != nil {
t.Fatal(err)
}

return cluster
}

type MockVault struct {
GetSecretsCalled bool
Data map[string]interface{}
Expand Down
Loading

0 comments on commit 830266c

Please sign in to comment.