Skip to content

Commit

Permalink
feat(tls): add optional --key-path parameter to `tls-custom private…
Browse files Browse the repository at this point in the history
…-key create` command (#1215)

This option is mutually exclusive with --key.

Co-authored-by: Kevin P. Fleming <kpfleming@users.noreply.github.com>
  • Loading branch information
rdoherty-fastly and kpfleming authored Jun 24, 2024
1 parent 20976a7 commit d728a93
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 9 deletions.
47 changes: 40 additions & 7 deletions pkg/commands/tls/custom/privatekey/create.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package privatekey

import (
"fmt"
"io"
"os"
"path/filepath"

"github.com/fastly/go-fastly/v9/fastly"

Expand All @@ -17,7 +20,8 @@ func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateComman
c.Globals = g

// Required.
c.CmdClause.Flag("key", "The contents of the private key. Must be a PEM-formatted key").Required().StringVar(&c.key)
c.CmdClause.Flag("key", "The contents of the private key. Must be a PEM-formatted key, mutually exclusive with --key-path").StringVar(&c.key)
c.CmdClause.Flag("key-path", "Filepath to a PEM-formatted key, mutually exclusive with --key").StringVar(&c.keyPath)
c.CmdClause.Flag("name", "A customizable name for your private key").Required().StringVar(&c.name)

return &c
Expand All @@ -27,13 +31,17 @@ func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateComman
type CreateCommand struct {
argparser.Base

key string
name string
key string
keyPath string
name string
}

// Exec invokes the application logic for the command.
func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error {
input := c.constructInput()
input, err := c.constructInput()
if err != nil {
return err
}

r, err := c.Globals.APIClient.CreatePrivateKey(input)
if err != nil {
Expand All @@ -48,11 +56,36 @@ func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error {
}

// constructInput transforms values parsed from CLI flags into an object to be used by the API client library.
func (c *CreateCommand) constructInput() *fastly.CreatePrivateKeyInput {
func (c *CreateCommand) constructInput() (*fastly.CreatePrivateKeyInput, error) {
var input fastly.CreatePrivateKeyInput

input.Key = c.key
if c.keyPath == "" && c.key == "" {
return nil, fmt.Errorf("neither --key-path or --key provided, one must be provided")
}

if c.keyPath != "" && c.key != "" {
return nil, fmt.Errorf("--key-path and --key provided, only one can be specified")
}

if c.key != "" {
input.Key = c.key
}

if c.keyPath != "" {
path, err := filepath.Abs(c.keyPath)
if err != nil {
return nil, fmt.Errorf("error parsing key-path '%s': %q", c.keyPath, err)
}

data, err := os.ReadFile(path) // #nosec
if err != nil {
return nil, fmt.Errorf("error reading key-path '%s': %q", c.keyPath, err)
}

input.Key = string(data)
}

input.Name = c.name

return &input
return &input, nil
}
32 changes: 30 additions & 2 deletions pkg/commands/tls/custom/privatekey/privatekey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ const (
)

func TestTLSCustomPrivateKeyCreate(t *testing.T) {
var content string
args := testutil.Args
scenarios := []testutil.TestScenario{
{
Name: "validate missing --key flag",
Name: "validate missing --key and --key-path flags",
Args: args("tls-custom private-key create --name example"),
WantError: "required flag --key not provided",
WantError: "neither --key-path or --key provided, one must be provided",
},
{
Name: "validate using both --key and --key-path flags",
Args: args("tls-custom private-key create --name example --key example --key-path foobar"),
WantError: "--key-path and --key provided, only one can be specified",
},
{
Name: "validate missing --name flag",
Expand All @@ -39,6 +45,7 @@ func TestTLSCustomPrivateKeyCreate(t *testing.T) {
Name: validateAPIError,
API: mock.API{
CreatePrivateKeyFn: func(i *fastly.CreatePrivateKeyInput) (*fastly.PrivateKey, error) {
content = i.Key
return nil, testutil.Err
},
},
Expand All @@ -49,6 +56,7 @@ func TestTLSCustomPrivateKeyCreate(t *testing.T) {
Name: validateAPISuccess,
API: mock.API{
CreatePrivateKeyFn: func(i *fastly.CreatePrivateKeyInput) (*fastly.PrivateKey, error) {
content = i.Key
return &fastly.PrivateKey{
ID: mockResponseID,
Name: i.Name,
Expand All @@ -58,6 +66,25 @@ func TestTLSCustomPrivateKeyCreate(t *testing.T) {
Args: args("tls-custom private-key create --key example --name example"),
WantOutput: "Created TLS Private Key 'example'",
},
{
Name: "validate custom key is submitted",
API: mock.API{
CreatePrivateKeyFn: func(i *fastly.CreatePrivateKeyInput) (*fastly.PrivateKey, error) {
content = i.Key
return &fastly.PrivateKey{
ID: mockResponseID,
Name: i.Name,
}, nil
},
},
Args: args("tls-custom private-key create --name example --key-path ./testdata/testkey.pem"),
WantOutput: "Created TLS Private Key 'example'",
},
{
Name: "validate invalid --key-path arg",
Args: args("tls-custom private-key create --name example --key-path ............"),
WantError: "error reading key-path",
},
}

for testcaseIdx := range scenarios {
Expand All @@ -72,6 +99,7 @@ func TestTLSCustomPrivateKeyCreate(t *testing.T) {
err := app.Run(testcase.Args, nil)
testutil.AssertErrorContains(t, err, testcase.WantError)
testutil.AssertStringContains(t, stdout.String(), testcase.WantOutput)
testutil.AssertPathContentFlag("key-path", testcase.WantError, testcase.Args, "testkey.pem", content, t)
})
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/commands/tls/custom/privatekey/testdata/testkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is a test key

0 comments on commit d728a93

Please sign in to comment.