Skip to content

Commit

Permalink
Merge pull request #62 from equinix/metros
Browse files Browse the repository at this point in the history
Implement Metros and update the default OS, plan, and location
  • Loading branch information
displague committed May 20, 2021
2 parents 323f06e + 359756b commit 7329688
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 22 deletions.
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
82 changes: 65 additions & 17 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"
)

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,19 +83,27 @@ 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",
Value: "baremetal_0",
Value: "c3.small.x86",
EnvVar: "METAL_PLAN",
},
mcnflag.StringFlag{
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

0 comments on commit 7329688

Please sign in to comment.