Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions cmd/base/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,22 @@ func fetchItems[T any](ctx context.Context, collection serverscom.Collection[T],

return collection.List(ctx)
}

func ValidateFlags(cmd *cobra.Command, required []string) error {
var missing []string

for _, flag := range required {
if !cmd.Flags().Changed(flag) {
missing = append(missing, "--"+flag)
}
}

if len(missing) > 0 {
return fmt.Errorf(
"provide all required flags (missing: %s)",
strings.Join(missing, ", "),
)
}

return nil
}
69 changes: 60 additions & 9 deletions cmd/entities/ssl/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package ssl
import (
"context"
"fmt"
"log"

serverscom "github.com/serverscom/serverscom-go-client/pkg"
"github.com/serverscom/srvctl/cmd/base"
"github.com/spf13/cobra"
)

type AddedFlags struct {
InputPath string
Name string
PublicKey string
PrivateKey string
ChainKey string
Labels []string
}

type SSLCreator interface {
Create(ctx context.Context, client *serverscom.Client, input any) (any, error)
NewCreateInput() any
Expand All @@ -30,9 +37,10 @@ func (c *SSLCustomCreateMgr) NewCreateInput() any {
}

func newAddCmd(cmdContext *base.CmdContext, sslType *SSLTypeCmd) *cobra.Command {
var path string
flags := &AddedFlags{}

cmd := &cobra.Command{
Use: "add --input <path>",
Use: "add",
Short: fmt.Sprintf("Create a %s", sslType.entityName),
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -44,7 +52,18 @@ func newAddCmd(cmdContext *base.CmdContext, sslType *SSLTypeCmd) *cobra.Command

input := sslType.managers.createMgr.NewCreateInput()

if err := base.ReadInputJSON(path, cmd.InOrStdin(), input); err != nil {
if flags.InputPath != "" {
if err := base.ReadInputJSON(flags.InputPath, cmd.InOrStdin(), input); err != nil {
return err
}
} else {
required := []string{"name", "public-key", "private-key"}
if err := base.ValidateFlags(cmd, required); err != nil {
return err
}
}

if err := flags.FillInput(cmd, input); err != nil {
return err
}

Expand All @@ -64,10 +83,42 @@ func newAddCmd(cmdContext *base.CmdContext, sslType *SSLTypeCmd) *cobra.Command
},
}

cmd.Flags().StringVarP(&path, "input", "i", "", "path to input file or '-' to read from stdin")
if err := cmd.MarkFlagRequired("input"); err != nil {
log.Fatal(err)
}
cmd.Flags().StringVarP(&flags.InputPath, "input", "i", "", "path to input file or '-' to read from stdin")
cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "A name of a SSL certificate")
cmd.Flags().StringVarP(&flags.PublicKey, "public-key", "", "", "A public-key of a SSL certificate")
cmd.Flags().StringVarP(&flags.PrivateKey, "private-key", "", "", "A private-key of a SSL certificate")
cmd.Flags().StringVarP(&flags.ChainKey, "chain-key", "", "", "A chain-key of a SSL certificate")
cmd.Flags().StringArrayVarP(&flags.Labels, "label", "l", []string{}, "string in key=value format")

return cmd
}

func (f *AddedFlags) FillInput(cmd *cobra.Command, input any) error {
sslInput, ok := input.(*serverscom.SSLCertificateCreateCustomInput)
if !ok {
return fmt.Errorf("invalid input type for custom SSL")
}

if cmd.Flags().Changed("name") {
sslInput.Name = f.Name
}
if cmd.Flags().Changed("public-key") {
sslInput.PublicKey = f.PublicKey
}
if cmd.Flags().Changed("private-key") {
sslInput.PrivateKey = f.PrivateKey
}
if cmd.Flags().Changed("chain-key") {
sslInput.ChainKey = f.ChainKey
}
if cmd.Flags().Changed("label") {
labelsMap, err := base.ParseLabels(f.Labels)
if err != nil {
return err
}

sslInput.Labels = labelsMap
}

return nil
}
25 changes: 24 additions & 1 deletion cmd/entities/ssl/ssl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestAddCustomSSLCmd(t *testing.T) {
expectError bool
}{
{
name: "create custom ssl cert",
name: "create custom ssl cert with input",
output: "json",
expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_custom.json")),
args: []string{"--input", filepath.Join(fixtureBasePath, "create_custom.json")},
Expand All @@ -86,6 +86,29 @@ func TestAddCustomSSLCmd(t *testing.T) {
Return(&testCustomSSL, nil)
},
},
{
name: "create custom ssl cert",
output: "json",
expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_custom.json")),
args: []string{
"--name", "test-ssl-custom",
"--public-key", "-----TEST public-key-----",
"--private-key", "-----TEST private-key-----",
"--chain-key", "-----TEST chain-key-----",
"--label", "foo=bar",
},
configureMock: func(mock *mocks.MockSSLCertificatesService) {
mock.EXPECT().
CreateCustom(gomock.Any(), serverscom.SSLCertificateCreateCustomInput{
Name: "test-ssl-custom",
PublicKey: "-----TEST public-key-----",
PrivateKey: "-----TEST private-key-----",
ChainKey: "-----TEST chain-key-----",
Labels: map[string]string{"foo": "bar"},
}).
Return(&testCustomSSL, nil)
},
},
{
name: "with error",
expectError: true,
Expand Down
Loading