Skip to content

Commit

Permalink
Updated metal-go client for sub-command devices
Browse files Browse the repository at this point in the history
  • Loading branch information
codinja1188 committed Aug 9, 2023
1 parent 15e23b9 commit 0354c50
Show file tree
Hide file tree
Showing 11 changed files with 623 additions and 70 deletions.
77 changes: 39 additions & 38 deletions internal/devices/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
package devices

import (
"context"
"fmt"
"os"
"time"

"github.com/packethost/packngo"
metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -64,62 +64,63 @@ func (c *Client) Create() *cobra.Command {
metal device create -p $METAL_PROJECT_ID -P c3.medium.x86 -m sv -H test-rocky -O rocky_8 -r 47161704-1715-4b45-8549-fb3f4b2c32c7`,

RunE: func(cmd *cobra.Command, args []string) error {
var endDt *packngo.Timestamp

if userdata != "" && userdataFile != "" {
return fmt.Errorf("either userdata or userdata-file should be set")
}
cmd.SilenceUsage = true

if userdataFile != "" {
userdataRaw, readErr := os.ReadFile(userdataFile)
if readErr != nil {
return fmt.Errorf("Could not read userdata-file: %w", readErr)
return fmt.Errorf("could not read userdata-file: %w", readErr)
}
userdata = string(userdataRaw)
}

if terminationTime != "" {
parsedTime, err := time.Parse(time.RFC3339, terminationTime)
if err != nil {
return fmt.Errorf("Could not parse time %q: %w", terminationTime, err)
}
endDt = &packngo.Timestamp{Time: parsedTime}
}

// var endDt time.Time

// if terminationTime != "" {
// parsedTime, err := time.Parse(time.RFC3339, terminationTime)
// if err != nil {
// return fmt.Errorf("could not parse time %q: %w", terminationTime, err)
// }
// endDt = parsedTime
// }
var facilityArgs []string

// var deviceCreateInFacilityInput *metal.DeviceCreateInFacilityInput
var request metal.ApiCreateDeviceRequest
if facility != "" {
facilityArgs = append(facilityArgs, facility)
}

request := &packngo.DeviceCreateRequest{
Hostname: hostname,
Plan: plan,
Facility: facilityArgs,
Metro: metro,
OS: operatingSystem,
BillingCycle: billingCycle,
ProjectID: projectID,
UserData: userdata,
CustomData: customdata,
IPXEScriptURL: ipxescripturl,
Tags: tags,
PublicIPv4SubnetSize: publicIPv4SubnetSize,
AlwaysPXE: alwaysPXE,
HardwareReservationID: hardwareReservationID,
SpotInstance: spotInstance,
SpotPriceMax: spotPriceMax,
TerminationTime: endDt,
facilityDeviceRequest := metal.CreateDeviceRequest{
DeviceCreateInFacilityInput: &metal.DeviceCreateInFacilityInput{
Facility: facilityArgs,
Plan: plan,
OperatingSystem: operatingSystem,
Hostname: &hostname,
},
}
request = c.Service.CreateDevice(context.Background(), projectID).CreateDeviceRequest(facilityDeviceRequest).Include(nil).Exclude(nil)
}
if metro != "" {

metroDeviceRequest := metal.CreateDeviceRequest{
DeviceCreateInMetroInput: &metal.DeviceCreateInMetroInput{
Metro: metro,
Plan: plan,
OperatingSystem: operatingSystem,
Hostname: &hostname,
},
}

device, _, err := c.Service.Create(request)
request = c.Service.CreateDevice(context.Background(), projectID).CreateDeviceRequest(metroDeviceRequest).Include(nil).Exclude(nil)
}
device, _, err := request.Execute()
if err != nil {
return fmt.Errorf("Could not create Device: %w", err)
return fmt.Errorf("could not create Device: %w", err)
}

header := []string{"ID", "Hostname", "OS", "State", "Created"}
data := make([][]string, 1)
data[0] = []string{device.ID, device.Hostname, device.OS.Name, device.State, device.Created}
data[0] = []string{device.GetId(), device.GetHostname(), *device.GetOperatingSystem().Name, device.GetState(), device.GetCreatedAt().String()}

return c.Out.Output(device, header, &data)
},
Expand Down
3 changes: 2 additions & 1 deletion internal/devices/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package devices

import (
"context"
"fmt"

"github.com/manifoldco/promptui"
Expand All @@ -31,7 +32,7 @@ func (c *Client) Delete() *cobra.Command {
var deviceID string
var force bool
deleteDevice := func(id string) error {
_, err := c.Service.Delete(id, force)
_, err := c.Service.DeleteDevice(context.Background(), id).ForceDelete(force).Execute()
if err != nil {
return err
}
Expand Down
12 changes: 7 additions & 5 deletions internal/devices/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
package devices

import (
metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/equinix/metal-cli/internal/outputs"
"github.com/packethost/packngo"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

type Client struct {
Servicer Servicer
Service packngo.DeviceService
Service metal.DevicesApiService
Out outputs.Outputer
}

Expand All @@ -47,7 +47,7 @@ func (c *Client) NewCommand() *cobra.Command {
}
}

c.Service = c.Servicer.API(cmd).Devices
c.Service = *c.Servicer.MetalAPI(cmd).DevicesApi
},
}

Expand All @@ -65,9 +65,11 @@ func (c *Client) NewCommand() *cobra.Command {
}

type Servicer interface {
API(*cobra.Command) *packngo.Client
ListOptions(defaultIncludes, defaultExcludes []string) *packngo.ListOptions
MetalAPI(*cobra.Command) *metal.APIClient
Config(cmd *cobra.Command) *viper.Viper
Filters() map[string]string
Includes(defaultIncludes []string) (incl []string)
Excludes(defaultExcludes []string) (excl []string)
}

func NewClient(s Servicer, out outputs.Outputer) *Client {
Expand Down
5 changes: 4 additions & 1 deletion internal/devices/reboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
package devices

import (
"context"
"fmt"

metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
)

Expand All @@ -38,7 +40,8 @@ func (c *Client) Reboot() *cobra.Command {

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
_, err := c.Service.Reboot(deviceID)
DeviceAction := metal.NewDeviceActionInput("reboot")
_, err := c.Service.PerformAction(context.Background(), deviceID).DeviceActionInput(*DeviceAction).Execute()
if err != nil {
return fmt.Errorf("Could not reboot Device: %w", err)
}
Expand Down
29 changes: 23 additions & 6 deletions internal/devices/reinstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
package devices

import (
"context"
"fmt"

"github.com/packethost/packngo"
metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
)

Expand All @@ -47,14 +48,30 @@ func (c *Client) Reinstall() *cobra.Command {
metal device reinstall -d 50382f72-02b7-4b40-ac8d-253713e1e174 -O ubuntu_22_04 --preserve-data`,
RunE: func(cmd *cobra.Command, args []string) error {

request := packngo.DeviceReinstallFields{
OperatingSystem: operatingSystem,
PreserveData: preserveData,
DeprovisionFast: deprovisionFast,
DeviceAction := metal.NewDeviceActionInput("reinstall")

if preserveData {
DeviceAction.PreserveData = &preserveData
}
if deprovisionFast {
DeviceAction.DeprovisionFast = &deprovisionFast
}
device, _, Err := c.Service.FindDeviceById(context.Background(), id).Execute()
if Err != nil {
fmt.Printf("Error when calling `DevicesApiService.FindDeviceByID``: %v\n", Err)
Err = fmt.Errorf("Could not reinstall Device: %w", Err)
return Err
}

if operatingSystem == "" || operatingSystem == "null" {
DeviceAction.SetOperatingSystem(device.OperatingSystem.GetSlug())
} else {
DeviceAction.OperatingSystem = &operatingSystem
}

_, err := c.Service.Reinstall(id, &request)
_, err := c.Service.PerformAction(context.Background(), id).DeviceActionInput(*DeviceAction).Execute()
if err != nil {
fmt.Printf("Error when calling `DevicesApiService.PerformAction``: %v\n", err)
err = fmt.Errorf("Could not reinstall Device: %w", err)
}

Expand Down
37 changes: 33 additions & 4 deletions internal/devices/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
package devices

import (
"context"
"fmt"
"strconv"

pager "github.com/equinix/metal-cli/internal/pagination"
"github.com/spf13/cobra"
)

Expand All @@ -48,26 +51,52 @@ func (c *Client) Retrieve() *cobra.Command {
cmd.SilenceUsage = true

if deviceID != "" {
device, _, err := c.Service.Get(deviceID, nil)
device, _, err := c.Service.FindDeviceById(context.Background(), deviceID).Include(c.Servicer.Includes(nil)).Exclude(c.Servicer.Excludes(nil)).Execute()
if err != nil {
return fmt.Errorf("Could not get Devices: %w", err)
}
header := []string{"ID", "Hostname", "OS", "State", "Created"}

data := make([][]string, 1)
data[0] = []string{device.ID, device.Hostname, device.OS.Name, device.State, device.Created}
data[0] = []string{device.GetId(), device.GetHostname(), device.OperatingSystem.GetName(), device.GetState(), device.GetCreatedAt().String()}

return c.Out.Output(device, header, &data)
}

devices, _, err := c.Service.List(projectID, c.Servicer.ListOptions(nil, nil))
request := c.Service.FindProjectDevices(context.Background(), projectID).Include(c.Servicer.Includes(nil)).Exclude(c.Servicer.Excludes(nil))
filters := c.Servicer.Filters()
if filters["type"] != "" {
request = request.Type_(filters["type"])
}

if filters["facility"] != "" {
request = request.Facility(filters["facility"])
}

if filters["hostname"] != "" {
request = request.Hostname(filters["hostname"])
}

if filters["reserved"] != "" {
value := filters["reserved"]
reserve, rerr := strconv.ParseBool(value)
if rerr != nil {
request = request.Reserved(reserve)
}
}

if filters["tag"] != "" {
request = request.Tag(filters["tag"])
}

devices, err := pager.GetProjectDevices(request)
if err != nil {
return fmt.Errorf("Could not list Devices: %w", err)
}
data := make([][]string, len(devices))

for i, dc := range devices {
data[i] = []string{dc.ID, dc.Hostname, dc.OS.Name, dc.State, dc.Created}
data[i] = []string{dc.GetId(), dc.GetHostname(), dc.OperatingSystem.GetName(), dc.GetState(), dc.GetCreatedAt().String()}
}
header := []string{"ID", "Hostname", "OS", "State", "Created"}

Expand Down
5 changes: 4 additions & 1 deletion internal/devices/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
package devices

import (
"context"
"fmt"

metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
)

Expand All @@ -38,7 +40,8 @@ func (c *Client) Start() *cobra.Command {

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
_, err := c.Service.PowerOn(deviceID)
DeviceAction := metal.NewDeviceActionInput("power_on")
_, err := c.Service.PerformAction(context.Background(), deviceID).DeviceActionInput(*DeviceAction).Execute()
if err != nil {
return fmt.Errorf("Could not start Device: %w", err)
}
Expand Down
5 changes: 4 additions & 1 deletion internal/devices/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
package devices

import (
"context"
"fmt"

metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
)

Expand All @@ -37,7 +39,8 @@ func (c *Client) Stop() *cobra.Command {

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
_, err := c.Service.PowerOff(deviceID)
DeviceAction := metal.NewDeviceActionInput("power_off")
_, err := c.Service.PerformAction(context.Background(), deviceID).DeviceActionInput(*DeviceAction).Execute()
if err != nil {
return fmt.Errorf("Could not stop Device: %w", err)
}
Expand Down
Loading

0 comments on commit 0354c50

Please sign in to comment.