Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Metros and update the default OS, plan, and location #62

Merged
merged 5 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ go 1.14

require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/carmo-evan/strtotime v0.0.0-20200108203155-3136cf889e3b // indirect
github.com/carmo-evan/strtotime v0.0.0-20200108203155-3136cf889e3b
github.com/docker/docker v0.0.0-20180805161158-f57f260b49b6 // indirect
github.com/docker/machine v0.16.2
github.com/google/go-cmp v0.3.0 // indirect
github.com/packethost/packngo v0.6.0
github.com/packethost/packngo v0.13.0
github.com/pkg/errors v0.8.1 // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/stretchr/testify v1.5.1
Expand Down
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/carmo-evan/strtotime v0.0.0-20200108203155-3136cf889e3b h1:U3vQoEOmB8zQ34LR8jQt6XMIdOiq49OZ1aPGjG1fJKE=
github.com/carmo-evan/strtotime v0.0.0-20200108203155-3136cf889e3b/go.mod h1:IqY2NtbgybBNEdxOZLXCF/OAAisAOiB4+F7/ovbQN8M=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -16,8 +15,8 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/packethost/packngo v0.6.0 h1:u2raV5kNHtYYoOwDhXy8daq1Q55HOUO+G4sPT86K9fk=
github.com/packethost/packngo v0.6.0/go.mod h1:YrtUNN9IRjjqN6zK+cy2IYoi3EjHfoWTWxJkI1I1Vk0=
github.com/packethost/packngo v0.13.0 h1:VIeDY/Uju53v8LAKxiqTrfR9jkpX5PhWdnQC0h3aUU8=
github.com/packethost/packngo v0.13.0/go.mod h1:YrtUNN9IRjjqN6zK+cy2IYoi3EjHfoWTWxJkI1I1Vk0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
80 changes: 64 additions & 16 deletions pkg/drivers/metal/metal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package metal
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
Expand All @@ -22,6 +23,8 @@ import (
const (
dockerConfigDir = "/etc/docker"
consumerToken = "24e70949af5ecd17fe8e867b335fc88e7de8bd4ad617c0403d8769a376ddea72"
defaultOS = "ubuntu_20_04"
defaultMetro = "DC"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metro should be lower-cased:

$ docker-machine create sloth --driver metal --metal-api-key=$API_KEY --metal-project-id=$PROJECT --metal-plan "baremetal_0" --metal-metro-code "DC"
Running pre-create checks...
Error with pre-create check: "metal requires a valid metro"

Runs as expected with "dc" from the CLI

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intended to change the default plan from baremetal_0 to c3.small.x86 so that the defaults would accommodate more users (new users).

)

var (
Expand All @@ -39,6 +42,7 @@ type Driver struct {
Plan string
HardwareReserverationID string
Facility string
Metro string
OperatingSystem string
BillingCycle string
DeviceID string
Expand Down Expand Up @@ -68,7 +72,7 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
return []mcnflag.Flag{
mcnflag.StringFlag{
Name: "metal-api-key",
Usage: "Equinix Metal api key",
Usage: "Equinix Metal API Key",
EnvVar: "METAL_AUTH_TOKEN",
},
mcnflag.StringFlag{
Expand All @@ -79,15 +83,23 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
mcnflag.StringFlag{
Name: "metal-os",
Usage: "Equinix Metal OS",
Value: "ubuntu_16_04",
Value: defaultOS,
EnvVar: "METAL_OS",
},
mcnflag.StringFlag{
Name: "metal-facility-code",
Usage: "Equinix Metal facility code",
Value: "ewr1",
EnvVar: "METAL_FACILITY_CODE",
},
mcnflag.StringFlag{
Name: "metal-metro-code",
Usage: fmt.Sprintf("Equinix Metal metro code (%q is used if empty and facility is not set)", defaultMetro),
EnvVar: "METAL_METRO_CODE",
// We don't set Value because Facility was previously required and
// defaulted. Existing configurations with "Facility" should not
// break. Setting a default metro value would break those
// configurations.
},
mcnflag.StringFlag{
Name: "metal-plan",
Usage: "Equinix Metal Server Plan",
Expand Down Expand Up @@ -149,6 +161,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.ProjectID = flags.String("metal-project-id")
d.OperatingSystem = flags.String("metal-os")
d.Facility = flags.String("metal-facility-code")
d.Metro = flags.String("metal-metro-code")
d.BillingCycle = flags.String("metal-billing-cycle")
d.UserAgentPrefix = flags.String("metal-ua-prefix")
d.UserDataFile = flags.String("metal-userdata")
Expand Down Expand Up @@ -214,22 +227,21 @@ func (d *Driver) PreCreateCheck() error {
return fmt.Errorf("specified --metal-os not one of %v", strings.Join(flavors, ", "))
}

if d.Facility == "any" {
return nil
if d.Metro == "" && d.Facility == "" {
d.Metro = defaultMetro
}

client := d.getClient()
facilities, _, err := client.Facilities.List(nil)
if err != nil {
return err
if d.Metro != "" && d.Facility != "" {
return fmt.Errorf("facility and metro can not be used together")
}
for _, facility := range facilities {
if facility.Code == d.Facility {
return nil
}

client := d.getClient()

if d.Metro != "" {
return validateMetro(client, d.Metro)
}

return fmt.Errorf("metal requires a valid facility")
return validateFacility(client, d.Facility)
}

func (d *Driver) Create() error {
Expand Down Expand Up @@ -262,7 +274,7 @@ func (d *Driver) Create() error {
Hostname: d.MachineName,
Plan: d.Plan,
HardwareReservationID: hardwareReservationId,
Facility: []string{d.Facility},
Metro: d.Metro,
OS: d.OperatingSystem,
BillingCycle: d.BillingCycle,
ProjectID: d.ProjectID,
Expand All @@ -273,12 +285,16 @@ func (d *Driver) Create() error {
TerminationTime: d.TerminationTime,
}

if d.Facility != "" {
createRequest.Facility = []string{d.Facility}
}

log.Info("Provisioning Equinix Metal server...")
newDevice, _, err := client.Devices.Create(createRequest)
if err != nil {
//cleanup ssh keys if device faild
if _, err := client.SSHKeys.Delete(d.SSHKeyID); err != nil {
if er, ok := err.(*packngo.ErrorResponse); !ok || er.Response.StatusCode != 404 {
if er, ok := err.(*packngo.ErrorResponse); !ok || er.Response.StatusCode != http.StatusNotFound {
return err
}
}
Expand Down Expand Up @@ -475,6 +491,38 @@ func (d *Driver) getOsFlavors() ([]string, error) {
return flavors, nil
}

func validateFacility(client *packngo.Client, facility string) error {
if facility == "any" {
return nil
}

facilities, _, err := client.Facilities.List(nil)
if err != nil {
return err
}
for _, f := range facilities {
if f.Code == facility {
return nil
}
}

return fmt.Errorf("metal requires a valid facility")
}

func validateMetro(client *packngo.Client, metro string) error {
metros, _, err := client.Metros.List(nil)
if err != nil {
return err
}
for _, m := range metros {
if m.Code == metro {
return nil
}
}

return fmt.Errorf("metal requires a valid metro")
}

func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
Expand Down