From 2418d9a0c1754fd3a85c0d40dc84d55a05da02ee Mon Sep 17 00:00:00 2001 From: Anton Bozhiy Date: Wed, 6 May 2026 12:38:07 +0300 Subject: [PATCH] Add ipxe-config flag support for hosts ebm add command --- cmd/entities/hosts/add.go | 5 ++ cmd/entities/hosts/hosts_test.go | 49 +++++++++++++++++ go.mod | 2 +- go.sum | 4 +- .../skeletons/templates/hosts/add_ebm.json | 4 +- .../entities/hosts/create_ebm_ipxe_input.json | 54 +++++++++++++++++++ 6 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 testdata/entities/hosts/create_ebm_ipxe_input.json diff --git a/cmd/entities/hosts/add.go b/cmd/entities/hosts/add.go index 75fe378..b12487d 100644 --- a/cmd/entities/hosts/add.go +++ b/cmd/entities/hosts/add.go @@ -17,6 +17,7 @@ type AddEBMFlags struct { ServerModelID int OperatingSystemID int Features []string + IPXEConfig string RAMSize int PublicUplinkID int PublicBandwidthID int @@ -56,6 +57,9 @@ func (f *AddEBMFlags) FillInput(cmd *cobra.Command, input *serverscom.DedicatedS if pflags.Changed("feature") { input.Features = f.Features } + if pflags.Changed("ipxe-config") { + input.IPXEConfig = &f.IPXEConfig + } if pflags.Changed("ram-size") { input.RAMSize = f.RAMSize } @@ -233,6 +237,7 @@ func newAddEBMCmd(cmdContext *base.CmdContext) *cobra.Command { cmd.Flags().IntVar(&flags.ServerModelID, "server-model-id", 0, "Use specific server model ID to create the server") cmd.Flags().IntVar(&flags.OperatingSystemID, "operating-system-id", 0, "Install the specific operating system") cmd.Flags().StringSliceVar(&flags.Features, "feature", nil, "Set of features") + cmd.Flags().StringVar(&flags.IPXEConfig, "ipxe-config", "", "iPXE script content") cmd.Flags().IntVar(&flags.RAMSize, "ram-size", 0, "Desired amount of RAM in GB") cmd.Flags().IntVar(&flags.PublicUplinkID, "public-uplink-id", 0, "The public uplink ID, can be omitted if do not want public uplink") cmd.Flags().IntVar(&flags.PrivateUplinkID, "private-uplink-id", 0, "The private uplink ID") diff --git a/cmd/entities/hosts/hosts_test.go b/cmd/entities/hosts/hosts_test.go index 0da4e7d..a5bd03b 100644 --- a/cmd/entities/hosts/hosts_test.go +++ b/cmd/entities/hosts/hosts_test.go @@ -352,6 +352,55 @@ func TestAddEBMCmd(t *testing.T) { Times(0) }, }, + { + name: "create ebm server with public_ipxe_boot feature and ipxe-config", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "create_ebm_resp.json")), + args: []string{ + "--input", filepath.Join(fixtureBasePath, "create_ebm_input.json"), + "--feature", "public_ipxe_boot", + "--ipxe-config", "#!ipxe\nboot", + }, + configureMock: func(mock *mocks.MockHostsService) { + input := expectedInput + input.Features = []string{"public_ipxe_boot"} + input.IPXEConfig = testutils.PtrString("#!ipxe\nboot") + mock.EXPECT(). + CreateDedicatedServers(gomock.Any(), input). + Return([]serverscom.DedicatedServer{testDS}, nil) + }, + }, + { + name: "create ebm server with ipxe-config flag", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "create_ebm_resp.json")), + args: []string{ + "--input", filepath.Join(fixtureBasePath, "create_ebm_input.json"), + "--ipxe-config", "#!ipxe\nboot", + }, + configureMock: func(mock *mocks.MockHostsService) { + input := expectedInput + input.IPXEConfig = testutils.PtrString("#!ipxe\nboot") + mock.EXPECT(). + CreateDedicatedServers(gomock.Any(), input). + Return([]serverscom.DedicatedServer{testDS}, nil) + }, + }, + { + name: "create ebm server with ipxe-config in input file", + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "create_ebm_resp.json")), + args: []string{ + "--input", filepath.Join(fixtureBasePath, "create_ebm_ipxe_input.json"), + }, + configureMock: func(mock *mocks.MockHostsService) { + input := expectedInput + input.IPXEConfig = testutils.PtrString("#!ipxe\nboot") + mock.EXPECT(). + CreateDedicatedServers(gomock.Any(), input). + Return([]serverscom.DedicatedServer{testDS}, nil) + }, + }, { name: "create ebm server with error", expectError: true, diff --git a/go.mod b/go.mod index 5192e56..aaac418 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/creack/pty v1.1.24 github.com/jmespath/go-jmespath v0.4.0 github.com/onsi/gomega v1.38.0 - github.com/serverscom/serverscom-go-client v1.0.30 + github.com/serverscom/serverscom-go-client v1.0.32 github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.7 github.com/spf13/viper v1.20.1 diff --git a/go.sum b/go.sum index 548699c..7cdcc3a 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.10.0 h1:FM8Cv6j2KqIhM2ZK7HZjm4mpj9NBktLgowT1aN9q5Cc= github.com/sagikazarmark/locafero v0.10.0/go.mod h1:Ieo3EUsjifvQu4NZwV5sPd4dwvu0OCgEQV7vjc9yDjw= -github.com/serverscom/serverscom-go-client v1.0.30 h1:J6bp3fVevZKzNduyj2XAZGvQVIReg3RMGcOS/Idz92c= -github.com/serverscom/serverscom-go-client v1.0.30/go.mod h1:/Nf+XygKOxm19Sl2gvMzT55O4X+tWDkj/UM4mjzfKgM= +github.com/serverscom/serverscom-go-client v1.0.32 h1:7pW3TJN4x7vF5QPSjBxQ3IKEr656LSaLgAZ3/09395k= +github.com/serverscom/serverscom-go-client v1.0.32/go.mod h1:/Nf+XygKOxm19Sl2gvMzT55O4X+tWDkj/UM4mjzfKgM= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= diff --git a/internal/output/skeletons/templates/hosts/add_ebm.json b/internal/output/skeletons/templates/hosts/add_ebm.json index 7e2575d..4678c8c 100644 --- a/internal/output/skeletons/templates/hosts/add_ebm.json +++ b/internal/output/skeletons/templates/hosts/add_ebm.json @@ -44,5 +44,7 @@ } } ], - "operating_system_id": "" + "operating_system_id": "", + "features": [], + "ipxe_config": "" } \ No newline at end of file diff --git a/testdata/entities/hosts/create_ebm_ipxe_input.json b/testdata/entities/hosts/create_ebm_ipxe_input.json new file mode 100644 index 0000000..af1aa3d --- /dev/null +++ b/testdata/entities/hosts/create_ebm_ipxe_input.json @@ -0,0 +1,54 @@ +{ + "server_model_id": 1234, + "location_id": 5678, + "ram_size": 16, + "uplink_models": { + "public": { + "id": 4321, + "bandwidth_model_id": 8765 + }, + "private": { + "id": 7890 + } + }, + "drives": { + "slots": [ + { + "position": 1, + "drive_model_id": 3456 + }, + { + "position": 2, + "drive_model_id": 3456 + } + ], + "layout": [ + { + "slot_positions": [ + 1, + 2 + ], + "raid": 1, + "partitions": [ + { + "target": "/boot", + "size": 500, + "fill": false, + "fs": "ext4" + } + ] + } + ] + }, + "hosts": [ + { + "hostname": "example.aa", + "public_ipv4_network_id": "PublicNet123", + "private_ipv4_network_id": "PrivateNet456", + "labels": { + "environment": "testing" + } + } + ], + "ipxe_config": "#!ipxe\nboot" +}