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
24 changes: 19 additions & 5 deletions cmd/entities/cloud-instances/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,41 @@ import (
)

type AddedFlags struct {
Skeleton bool
InputPath string
}

func newAddCmd(cmdContext *base.CmdContext) *cobra.Command {
flags := &AddedFlags{}

cmd := &cobra.Command{
Use: "add --input <path>",
Use: "add",
Short: "Add cloud instance",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
formatter := cmdContext.GetOrCreateFormatter(cmd)

if flags.Skeleton {
return formatter.FormatSkeleton("cloud-instances/add.json")
}

manager := cmdContext.GetManager()
ctx, cancel := base.SetupContext(cmd, manager)
defer cancel()

base.SetupProxy(cmd, manager)

input := serverscom.CloudComputingInstanceCreateInput{}
if err := base.ReadInputJSON(flags.InputPath, cmd.InOrStdin(), &input); err != nil {
return err

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

scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient()
Expand All @@ -36,15 +51,14 @@ func newAddCmd(cmdContext *base.CmdContext) *cobra.Command {
}

if out != nil {
formatter := cmdContext.GetOrCreateFormatter(cmd)
return formatter.Format(out)
}
return nil
},
}

cmd.Flags().StringVarP(&flags.InputPath, "input", "i", "", "path to input file or '-' to read from stdin")
_ = cmd.MarkFlagRequired("input")
cmd.Flags().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed")

return cmd
}
22 changes: 17 additions & 5 deletions cmd/entities/cloud-instances/cloud_instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import (
)

var (
fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "cloud-instances")
fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)
testCloudInstanceID = "test-instance-id"
testCloudInstance = serverscom.CloudComputingInstance{
fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "cloud-instances")
skeletonTemplatePath = filepath.Join("..", "..", "..", "internal", "output", "skeletons", "templates", "cloud-instances")
fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)
testCloudInstanceID = "test-instance-id"
testCloudInstance = serverscom.CloudComputingInstance{
ID: testCloudInstanceID,
Name: "test-instance",
RegionID: 1,
Expand Down Expand Up @@ -308,6 +309,17 @@ func TestAddCloudInstancesCmd(t *testing.T) {
Return(&testCloudInstance, nil)
},
},
{
name: "skeleton for cloud instance input",
output: "json",
args: []string{"--skeleton"},
expectedOutput: testutils.ReadFixture(filepath.Join(skeletonTemplatePath, "add.json")),
configureMock: func(mock *mocks.MockCloudComputingInstancesService) {
mock.EXPECT().
Create(gomock.Any(), gomock.Any()).
Times(0)
},
},
{
name: "create cloud instance with error",
expectError: true,
Expand Down Expand Up @@ -353,7 +365,7 @@ func TestAddCloudInstancesCmd(t *testing.T) {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).To(BeNil())
g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput)))
g.Expect(builder.GetOutput()).To(MatchJSON(tc.expectedOutput))
}
})
}
Expand Down
49 changes: 37 additions & 12 deletions cmd/entities/hosts/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package hosts

import (
"fmt"
"log"
"os"

"maps"
"os"

serverscom "github.com/serverscom/serverscom-go-client/pkg"
"github.com/serverscom/srvctl/cmd/base"
Expand All @@ -14,6 +12,7 @@ import (
)

type AddDSFlags struct {
Skeleton bool
InputPath string
LocationID int
ServerModelID int
Expand All @@ -32,6 +31,11 @@ type AddDSFlags struct {
Labels map[string]string
}

type AddSBMFlags struct {
Skeleton bool
InputPath string
}

func applyFlagsToInput(
input *serverscom.DedicatedServerCreateInput,
flags *AddDSFlags,
Expand Down Expand Up @@ -132,6 +136,11 @@ func newAddDSCmd(cmdContext *base.CmdContext) *cobra.Command {
Short: "Create a dedicated server",
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
formatter := cmdContext.GetOrCreateFormatter(cmd)

if flags.Skeleton {
return formatter.FormatSkeleton("hosts/add_ds.json")
}

manager := cmdContext.GetManager()
ctx, cancel := base.SetupContext(cmd, manager)
Expand All @@ -145,6 +154,11 @@ func newAddDSCmd(cmdContext *base.CmdContext) *cobra.Command {
if err := base.ReadInputJSON(flags.InputPath, cmd.InOrStdin(), &input); err != nil {
return err
}
} else {
required := []string{"input"}
if err := base.ValidateFlags(cmd, required); err != nil {
return err
}
}

if len(input.Hosts) == 0 && len(args) == 0 {
Expand All @@ -171,7 +185,6 @@ func newAddDSCmd(cmdContext *base.CmdContext) *cobra.Command {
}

if server != nil {
formatter := cmdContext.GetOrCreateFormatter(cmd)
return formatter.Format(server)
}

Expand All @@ -180,6 +193,7 @@ func newAddDSCmd(cmdContext *base.CmdContext) *cobra.Command {
}

cmd.Flags().StringVarP(&flags.InputPath, "input", "i", "", "path to input file or '-' to read from stdin")
cmd.Flags().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed")

cmd.Flags().IntVar(&flags.LocationID, "location-id", 0, "Create the server(s) in the specific location ID")
cmd.Flags().IntVar(&flags.ServerModelID, "server-model-id", 0, "Use specific server model ID to create the server")
Expand All @@ -201,12 +215,19 @@ func newAddDSCmd(cmdContext *base.CmdContext) *cobra.Command {
}

func newAddSBMCmd(cmdContext *base.CmdContext) *cobra.Command {
var path string
flags := &AddSBMFlags{}

cmd := &cobra.Command{
Use: "add --input <path>",
Short: "Create an SBM server",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
formatter := cmdContext.GetOrCreateFormatter(cmd)

if flags.Skeleton {
return formatter.FormatSkeleton("hosts/add_sbm.json")
}

manager := cmdContext.GetManager()
ctx, cancel := base.SetupContext(cmd, manager)
defer cancel()
Expand All @@ -215,8 +236,15 @@ func newAddSBMCmd(cmdContext *base.CmdContext) *cobra.Command {

input := serverscom.SBMServerCreateInput{}

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

scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient()
Expand All @@ -227,18 +255,15 @@ func newAddSBMCmd(cmdContext *base.CmdContext) *cobra.Command {
}

if server != nil {
formatter := cmdContext.GetOrCreateFormatter(cmd)
return formatter.Format(server)
}

return nil
},
}

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().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed")

return cmd
}
41 changes: 32 additions & 9 deletions cmd/entities/hosts/hosts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import (
)

var (
testId = "testId"
testNetworkId = "testNetId"
fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "hosts")
fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)
testPublicIP = "1.2.3.4"
testLocationCode = "test"
testHost = serverscom.Host{
testId = "testId"
testNetworkId = "testNetId"
fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "hosts")
skeletonTemplatePath = filepath.Join("..", "..", "..", "internal", "output", "skeletons", "templates", "hosts")
fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)
testPublicIP = "1.2.3.4"
testLocationCode = "test"
testHost = serverscom.Host{
ID: testId,
Title: "example.aa",
Status: "active",
Expand Down Expand Up @@ -340,6 +341,17 @@ func TestAddDSCmd(t *testing.T) {
Return([]serverscom.DedicatedServer{testDS}, nil)
},
},
{
name: "skeleton for dedicated server input",
output: "json",
args: []string{"--skeleton"},
expectedOutput: testutils.ReadFixture(filepath.Join(skeletonTemplatePath, "add_ds.json")),
configureMock: func(mock *mocks.MockHostsService) {
mock.EXPECT().
CreateDedicatedServers(gomock.Any(), gomock.Any()).
Times(0)
},
},
{
name: "create dedicated server with error",
expectError: true,
Expand Down Expand Up @@ -385,7 +397,7 @@ func TestAddDSCmd(t *testing.T) {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).To(BeNil())
g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput)))
g.Expect(builder.GetOutput()).To(MatchJSON(tc.expectedOutput))
}
})
}
Expand Down Expand Up @@ -424,6 +436,17 @@ func TestAddSBMCmd(t *testing.T) {
Return([]serverscom.SBMServer{testSBM}, nil)
},
},
{
name: "skeleton for SBM server input",
output: "json",
args: []string{"--skeleton"},
expectedOutput: testutils.ReadFixture(filepath.Join(skeletonTemplatePath, "add_sbm.json")),
configureMock: func(mock *mocks.MockHostsService) {
mock.EXPECT().
CreateSBMServers(gomock.Any(), gomock.Any()).
Times(0)
},
},
{
name: "create SBM server with error",
expectError: true,
Expand Down Expand Up @@ -469,7 +492,7 @@ func TestAddSBMCmd(t *testing.T) {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).To(BeNil())
g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput)))
g.Expect(builder.GetOutput()).To(MatchJSON(tc.expectedOutput))
}
})
}
Expand Down
33 changes: 23 additions & 10 deletions cmd/entities/hosts/reinstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package hosts
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 {
Skeleton bool
InputPath string
}

type HostReinstaller interface {
Reinstall(ctx context.Context, client *serverscom.Client, id string, input any) (any, error)
NewReinstallInput() any
Expand Down Expand Up @@ -44,22 +47,35 @@ func (c *SBMReinstallMgr) NewReinstallInput() any {
}

func newReinstallCmd(cmdContext *base.CmdContext, hostType *HostTypeCmd) *cobra.Command {
var path string
flags := &AddedFlags{}

cmd := &cobra.Command{
Use: "reinstall <id>",
Short: fmt.Sprintf("Reinstall OS for a %s", hostType.entityName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
formatter := cmdContext.GetOrCreateFormatter(cmd)

if flags.Skeleton {
return formatter.FormatSkeleton("hosts/reinstall.json")
}

manager := cmdContext.GetManager()
ctx, cancel := base.SetupContext(cmd, manager)
defer cancel()
base.SetupProxy(cmd, manager)

input := hostType.managers.reinstallMgr.NewReinstallInput()

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

scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient()
Expand All @@ -71,17 +87,14 @@ func newReinstallCmd(cmdContext *base.CmdContext, hostType *HostTypeCmd) *cobra.
}

if server != nil {
formatter := cmdContext.GetOrCreateFormatter(cmd)
return formatter.Format(server)
}
return nil
},
}

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().BoolVarP(&flags.Skeleton, "skeleton", "s", false, "JSON object with structure that is required to be passed")

return cmd
}
Loading
Loading