Skip to content
This repository has been archived by the owner on Nov 16, 2020. It is now read-only.

Commit

Permalink
Use client SDK for secrets and services in CLI
Browse files Browse the repository at this point in the history
* Also start adding unittests for the above CLI functionality
* Get the error cause for API errors
  • Loading branch information
berndtj committed Jun 8, 2018
1 parent 93a1770 commit cd131ec
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 210 deletions.
1 change: 1 addition & 0 deletions pkg/client/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (c *DefaultSecretsClient) UpdateSecret(ctx context.Context, organizationID
Context: ctx,
XDispatchOrg: c.getOrgID(organizationID),
Secret: secret,
SecretName: *secret.Name,
}
response, err := c.client.Secret.UpdateSecret(&params, c.auth)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions pkg/dispatchcli/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,15 @@ func NewCmdCreate(out io.Writer, errOut io.Writer) *cobra.Command {
imgClient := imageManagerClient()
eventClient := eventManagerClient()
apiClient := apiManagerClient()
secClient := secretStoreClient()
svcClient := serviceManagerClient()

createMap := map[string]ModelAction{
utils.ImageKind: CallCreateImage(imgClient),
utils.BaseImageKind: CallCreateBaseImage(imgClient),
utils.FunctionKind: CallCreateFunction(fnClient),
utils.SecretKind: CallCreateSecret,
utils.ServiceInstanceKind: CallCreateServiceInstance,
utils.SecretKind: CallCreateSecret(secClient),
utils.ServiceInstanceKind: CallCreateServiceInstance(svcClient),
utils.PolicyKind: CallCreatePolicy,
utils.ApplicationKind: CallCreateApplication,
utils.ServiceAccountKind: CallCreateServiceAccount,
Expand Down
2 changes: 1 addition & 1 deletion pkg/dispatchcli/cmd/create_baseimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func CallCreateBaseImage(c client.ImagesClient) ModelAction {

created, err := c.CreateBaseImage(context.TODO(), dispatchConfig.Organization, baseImage)
if err != nil {
return formatAPIError(err, baseImage.Name)
return formatAPIError(err, *baseImage.Name)
}
*baseImage = *created
return nil
Expand Down
43 changes: 20 additions & 23 deletions pkg/dispatchcli/cmd/create_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"golang.org/x/net/context"

"github.com/vmware/dispatch/pkg/api/v1"
"github.com/vmware/dispatch/pkg/client"
"github.com/vmware/dispatch/pkg/dispatchcli/i18n"
secret "github.com/vmware/dispatch/pkg/secret-store/gen/client/secret"
)

var (
Expand All @@ -32,25 +32,6 @@ var (
createSecretExample = i18n.T(`create a secret`)
)

// CallCreateSecret makes the API call to create a secret
func CallCreateSecret(s interface{}) error {
client := secretStoreClient()
body := s.(*v1.Secret)

params := &secret.AddSecretParams{
Secret: body,
Context: context.Background(),
}

created, err := client.Secret.AddSecret(params, GetAuthInfoWriter())
if err != nil {
return formatAPIError(err, params)
}

*body = *created.Payload
return nil
}

// NewCmdCreateSecret creates command responsible for secret creation.
func NewCmdCreateSecret(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Expand All @@ -60,15 +41,31 @@ func NewCmdCreateSecret(out io.Writer, errOut io.Writer) *cobra.Command {
Example: createSecretExample,
Args: cobra.MinimumNArgs(2),
Run: func(cmd *cobra.Command, args []string) {
err := createSecret(out, errOut, cmd, args)
c := secretStoreClient()
err := createSecret(out, errOut, cmd, args, c)
CheckErr(err)
},
}
cmd.Flags().StringVarP(&cmdFlagApplication, "application", "a", "", "associate with an application")
return cmd
}

func createSecret(out, errOut io.Writer, cmd *cobra.Command, args []string) error {
// CallCreateSecret makes the API call to create a secret
func CallCreateSecret(c client.SecretsClient) ModelAction {
return func(s interface{}) error {
secretModel := s.(*v1.Secret)

created, err := c.CreateSecret(context.TODO(), dispatchConfig.Organization, secretModel)
if err != nil {
return formatAPIError(err, *secretModel.Name)
}

*secretModel = *created
return nil
}
}

func createSecret(out, errOut io.Writer, cmd *cobra.Command, args []string, c client.SecretsClient) error {
secretPath := args[1]

body := &v1.Secret{
Expand All @@ -93,7 +90,7 @@ func createSecret(out, errOut io.Writer, cmd *cobra.Command, args []string) erro
Value: cmdFlagApplication,
})
}
err := CallCreateSecret(body)
err := CallCreateSecret(c)(body)
if err != nil {
return err
}
Expand Down
42 changes: 42 additions & 0 deletions pkg/dispatchcli/cmd/create_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ package cmd

import (
"bytes"
"encoding/json"
"io/ioutil"
"os"
"strings"
"testing"

"github.com/go-openapi/swag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/vmware/dispatch/pkg/api/v1"
"github.com/vmware/dispatch/pkg/client/mocks"
)

func TestCmdCreateSecret(t *testing.T) {
Expand All @@ -23,3 +29,39 @@ func TestCmdCreateSecret(t *testing.T) {
assert.Nil(t, err)
assert.True(t, strings.Contains(buf.String(), "Create a dispatch secret"))
}

func TestCreateSecret(t *testing.T) {
var stdout, stderr bytes.Buffer

cli := NewCLI(os.Stdin, &stdout, &stderr)

sc := &mocks.SecretsClient{}

body := map[string]string{"secretKey": "secretValue"}

tmpfile, err := ioutil.TempFile("", "createSecret")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name()) // clean up

enc := json.NewEncoder(tmpfile)
err = enc.Encode(body)
assert.NoError(t, err)

args := []string{"test", tmpfile.Name()}
dispatchConfig.JSON = true

secret := &v1.Secret{
Name: swag.String(args[0]),
Secrets: body,
}

sc.On("CreateSecret", mock.Anything, mock.Anything, secret).Once().Return(secret, nil)
err = createSecret(&stdout, &stderr, cli, args, sc)
assert.NoError(t, err)

secObj := make(map[string]interface{})
err = json.Unmarshal(stdout.Bytes(), &secObj)
assert.NoError(t, err)
assert.EqualValues(t, "test", secObj["name"])
assert.EqualValues(t, map[string]interface{}{"secretKey": "secretValue"}, secObj["secrets"])
}
31 changes: 14 additions & 17 deletions pkg/dispatchcli/cmd/create_serviceinstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
"golang.org/x/net/context"

"github.com/vmware/dispatch/pkg/api/v1"
"github.com/vmware/dispatch/pkg/client"
"github.com/vmware/dispatch/pkg/dispatchcli/i18n"
serviceinstance "github.com/vmware/dispatch/pkg/service-manager/gen/client/service_instance"
)

var (
Expand All @@ -32,22 +32,18 @@ var (
)

// CallCreateServiceInstance makes the API call to create a service instance
func CallCreateServiceInstance(s interface{}) error {
client := serviceManagerClient()
body := s.(*v1.ServiceInstance)
func CallCreateServiceInstance(c client.ServicesClient) ModelAction {
return func(s interface{}) error {
serviceInstanceModel := s.(*v1.ServiceInstance)

params := &serviceinstance.AddServiceInstanceParams{
Body: body,
Context: context.Background(),
}
created, err := c.CreateServiceInstance(context.TODO(), serviceInstanceModel)
if err != nil {
return formatAPIError(err, *serviceInstanceModel.Name)
}

created, err := client.ServiceInstance.AddServiceInstance(params, GetAuthInfoWriter())
if err != nil {
return formatAPIError(err, params)
*serviceInstanceModel = *created
return nil
}

*body = *created.Payload
return nil
}

// NewCmdCreateServiceInstance creates command responsible for service instance creation.
Expand All @@ -59,7 +55,8 @@ func NewCmdCreateServiceInstance(out io.Writer, errOut io.Writer) *cobra.Command
Example: createServiceInstanceExample,
Args: cobra.MinimumNArgs(3),
Run: func(cmd *cobra.Command, args []string) {
err := createServiceInstance(out, errOut, cmd, args)
c := serviceManagerClient()
err := createServiceInstance(out, errOut, cmd, args, c)
CheckErr(err)
},
}
Expand All @@ -84,7 +81,7 @@ func parseParameters(p string) (map[string]interface{}, error) {
return nil, nil
}

func createServiceInstance(out, errOut io.Writer, cmd *cobra.Command, args []string) error {
func createServiceInstance(out, errOut io.Writer, cmd *cobra.Command, args []string, c client.ServicesClient) error {
body := &v1.ServiceInstance{
Name: &args[0],
ServiceClass: &args[1],
Expand Down Expand Up @@ -115,7 +112,7 @@ func createServiceInstance(out, errOut io.Writer, cmd *cobra.Command, args []str
}
body.Binding.Parameters = p

err = CallCreateServiceInstance(body)
err = CallCreateServiceInstance(c)(body)
if err != nil {
return err
}
Expand Down
46 changes: 46 additions & 0 deletions pkg/dispatchcli/cmd/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ package cmd
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strings"
"testing"

"github.com/go-openapi/swag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/vmware/dispatch/pkg/api/v1"
"github.com/vmware/dispatch/pkg/client/mocks"
"github.com/vmware/dispatch/pkg/utils"
)

func TestCmdCreate(t *testing.T) {
Expand All @@ -26,3 +32,43 @@ func TestCmdCreate(t *testing.T) {
assert.Nil(t, err)
assert.True(t, strings.Contains(buf.String(), "Create a resource"))
}

var secretSeed = `kind: Secret
name: open-sesame
secrets:
password: OpenSesame
tags:
- key: role
value: test`

func TestCreateBatchSecret(t *testing.T) {
var stdout, stderr bytes.Buffer

cli := NewCLI(os.Stdin, &stdout, &stderr)

tmpfile, err := ioutil.TempFile("", "seed")
assert.NoError(t, err)
defer os.Remove(tmpfile.Name()) // clean up

_, err = tmpfile.Write([]byte(secretSeed))
assert.NoError(t, err)

sc := &mocks.SecretsClient{}

createMap := map[string]ModelAction{
utils.SecretKind: CallCreateSecret(sc),
}

secret := &v1.Secret{
Kind: utils.SecretKind,
Name: swag.String("open-sesame"),
Secrets: map[string]string{"password": "OpenSesame"},
Tags: []*v1.Tag{&v1.Tag{Key: "role", Value: "test"}},
}

sc.On("CreateSecret", mock.Anything, mock.Anything, secret).Once().Return(secret, nil)

file = tmpfile.Name()
err = importFile(&stdout, &stderr, cli, nil, createMap, "Created")
assert.Nil(t, err)
}
6 changes: 4 additions & 2 deletions pkg/dispatchcli/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,18 @@ func NewCmdDelete(out io.Writer, errOut io.Writer) *cobra.Command {
imgClient := imageManagerClient()
eventClient := eventManagerClient()
apiClient := apiManagerClient()
secClient := secretStoreClient()
svcClient := serviceManagerClient()

deleteMap := map[string]ModelAction{
utils.ImageKind: CallDeleteImage(imgClient),
utils.BaseImageKind: CallDeleteBaseImage(imgClient),
utils.FunctionKind: CallDeleteFunction(fnClient),
utils.SecretKind: CallDeleteSecret,
utils.SecretKind: CallDeleteSecret(secClient),
utils.ApplicationKind: CallDeleteApplication,
utils.PolicyKind: CallDeletePolicy,
utils.ServiceAccountKind: CallDeleteServiceAccount,
utils.ServiceInstanceKind: CallDeleteServiceInstance,
utils.ServiceInstanceKind: CallDeleteServiceInstance(svcClient),
utils.DriverTypeKind: CallDeleteEventDriverType(eventClient),
utils.DriverKind: CallDeleteEventDriver(eventClient),
utils.SubscriptionKind: CallDeleteSubscription(eventClient),
Expand Down
37 changes: 16 additions & 21 deletions pkg/dispatchcli/cmd/delete_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import (
"golang.org/x/net/context"

"github.com/vmware/dispatch/pkg/api/v1"
"github.com/vmware/dispatch/pkg/dispatchcli/cmd/utils"
"github.com/vmware/dispatch/pkg/client"
"github.com/vmware/dispatch/pkg/dispatchcli/i18n"
secret "github.com/vmware/dispatch/pkg/secret-store/gen/client/secret"
)

var (
Expand All @@ -36,7 +35,8 @@ func NewCmdDeleteSecret(out io.Writer, errOut io.Writer) *cobra.Command {
Args: cobra.ExactArgs(1),
Aliases: []string{"secrets"},
Run: func(cmd *cobra.Command, args []string) {
err := deleteSecret(out, errOut, cmd, args)
c := secretStoreClient()
err := deleteSecret(out, errOut, cmd, args, c)
CheckErr(err)
},
}
Expand All @@ -45,31 +45,26 @@ func NewCmdDeleteSecret(out io.Writer, errOut io.Writer) *cobra.Command {
}

// CallDeleteSecret makes the API call to delete a secret
func CallDeleteSecret(s interface{}) error {
client := secretStoreClient()
secretModel := s.(*v1.Secret)
params := &secret.DeleteSecretParams{
SecretName: *secretModel.Name,
Context: context.Background(),
Tags: []string{},
}
utils.AppendApplication(&params.Tags, cmdFlagApplication)
func CallDeleteSecret(c client.SecretsClient) ModelAction {
return func(s interface{}) error {
secretModel := s.(*v1.Secret)

_, err := client.Secret.DeleteSecret(params, GetAuthInfoWriter())
if err != nil {
return formatAPIError(err, params)
err := c.DeleteSecret(context.TODO(), dispatchConfig.Organization, *secretModel.Name)
if err != nil {
return formatAPIError(err, *secretModel.Name)
}
// No content is returned from secret... should return secret payload
// like all other endpoints.
// *secretModel = *deleted.Payload
return nil
}
// No content is returned from secret... should return secret payload
// like all other endpoints.
// *secretModel = *deleted.Payload
return nil
}

func deleteSecret(out, errOut io.Writer, cmd *cobra.Command, args []string) error {
func deleteSecret(out, errOut io.Writer, cmd *cobra.Command, args []string, c client.SecretsClient) error {
secretModel := v1.Secret{
Name: &args[0],
}
err := CallDeleteSecret(&secretModel)
err := CallDeleteSecret(c)(&secretModel)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit cd131ec

Please sign in to comment.