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

feat(as): add support for apple silicon M1-M #776

Merged
merged 5 commits into from
Feb 5, 2021
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/google/go-cmp v0.5.4
github.com/hashicorp/go-retryablehttp v0.6.8
github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.0
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210122093136-86a7a7845e32
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210202173413-337fb17121a1
github.com/stretchr/testify v1.6.1
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210122093136-86a7a7845e32 h1:XEqVuIfQTWwFfeBJZ0rxXoeT2blrKefX01TtUrxg+y0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210122093136-86a7a7845e32/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210202173413-337fb17121a1 h1:vytHInJpH5I4FheLyFW2wu5LmtcQOJhetm3+jaVGp74=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210202173413-337fb17121a1/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
Expand Down
37 changes: 37 additions & 0 deletions scaleway/helpers_apple_silicon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package scaleway

import (
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
applesilicon "github.com/scaleway/scaleway-sdk-go/api/applesilicon/v1alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

const (
defaultAppleSiliconServerTimeout = 2 * time.Minute
)

// asAPIWithZone returns a new apple silicon API and the zone
func asAPIWithZone(d *schema.ResourceData, m interface{}) (*applesilicon.API, scw.Zone, error) {
meta := m.(*Meta)
asAPI := applesilicon.NewAPI(meta.scwClient)

zone, err := extractZone(d, meta)
if err != nil {
return nil, "", err
}
return asAPI, zone, nil
}

// asAPIWithZoneAndID returns an apple silicon API with zone and ID extracted from the state
func asAPIWithZoneAndID(m interface{}, id string) (*applesilicon.API, scw.Zone, string, error) {
meta := m.(*Meta)
asAPI := applesilicon.NewAPI(meta.scwClient)

zone, ID, err := parseZonedID(id)
if err != nil {
return nil, "", "", err
}
return asAPI, zone, ID, nil
}
1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {

ResourcesMap: map[string]*schema.Resource{
"scaleway_account_ssh_key": resourceScalewayAccountSSKKey(),
"scaleway_apple_silicon_server": resourceScalewayAppleSiliconServer(),
"scaleway_baremetal_server": resourceScalewayBaremetalServer(),
"scaleway_instance_ip": resourceScalewayInstanceIP(),
"scaleway_instance_ip_reverse_dns": resourceScalewayInstanceIPReverseDNS(),
Expand Down
179 changes: 179 additions & 0 deletions scaleway/resource_apple_silicon_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package scaleway

import (
"context"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
applesilicon "github.com/scaleway/scaleway-sdk-go/api/applesilicon/v1alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func resourceScalewayAppleSiliconServer() *schema.Resource {
return &schema.Resource{
CreateContext: resourceScalewayAppleSiliconServerCreate,
ReadContext: resourceScalewayAppleSiliconServerRead,
UpdateContext: resourceScalewayAppleSiliconServerUpdate,
DeleteContext: resourceScalewayAppleSiliconServerDelete,
Timeouts: &schema.ResourceTimeout{
Default: schema.DefaultTimeout(defaultAppleSiliconServerTimeout),
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "Name of the server",
Computed: true,
Optional: true,
},
"type": {
Type: schema.TypeString,
Description: "Type of the server",
Required: true,
ForceNew: true,
},

// Computed
"ip": {
Type: schema.TypeString,
Description: "IPv4 address of the server",
Computed: true,
},
"vnc_url": {
Type: schema.TypeString,
Description: "VNC url use to connect remotely to the desktop GUI",
Computed: true,
},

"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the creation of the server",
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the last update of the server",
},
"deletable_at": {
Type: schema.TypeString,
Computed: true,
Description: "The minimal date and time on which you can delete this server due to Apple licence",
},

// Common
"zone": zoneSchema(),
"organization_id": organizationIDSchema(),
"project_id": projectIDSchema(),
},
}
}

func resourceScalewayAppleSiliconServerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
asAPI, zone, err := asAPIWithZone(d, m)
if err != nil {
return diag.FromErr(err)
}

createReq := &applesilicon.CreateServerRequest{
Name: expandOrGenerateString(d.Get("name"), "m1"),
Type: d.Get("type").(string),
ProjectID: d.Get("project_id").(string),
}

res, err := asAPI.CreateServer(createReq, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

d.SetId(newZonedIDString(zone, res.ID))

_, err = asAPI.WaitForServer(&applesilicon.WaitForServerRequest{
ServerID: res.ID,
Timeout: scw.TimeDurationPtr(defaultAppleSiliconServerTimeout),
RetryInterval: nil,
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

return resourceScalewayRdbInstanceRead(ctx, d, m)
}

func resourceScalewayAppleSiliconServerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
asAPI, zone, ID, err := asAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

res, err := asAPI.GetServer(&applesilicon.GetServerRequest{
Zone: zone,
ServerID: ID,
}, scw.WithContext(ctx))
if err != nil {
if is404Error(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}

_ = d.Set("name", res.Name)
_ = d.Set("type", res.Type)
_ = d.Set("created_at", res.CreatedAt.Format(time.RFC3339))
_ = d.Set("updated_at", res.UpdatedAt.Format(time.RFC3339))
_ = d.Set("deletable_at", res.DeletableAt.Format(time.RFC3339))
_ = d.Set("ip", res.IP.String())
_ = d.Set("vnc_url", res.VncURL)

_ = d.Set("zone", zone.String())
_ = d.Set("organization_id", res.OrganizationID)
_ = d.Set("project_id", res.ProjectID)

return nil
}

func resourceScalewayAppleSiliconServerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
asAPI, zone, ID, err := asAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

req := &applesilicon.UpdateServerRequest{
Zone: zone,
ServerID: ID,
}

if d.HasChange("name") {
req.Name = expandStringPtr(d.Get("name"))
}

_, err = asAPI.UpdateServer(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

return resourceScalewayAppleSiliconServerRead(ctx, d, m)
}

func resourceScalewayAppleSiliconServerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
asAPI, zone, ID, err := asAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

err = asAPI.DeleteServer(&applesilicon.DeleteServerRequest{
Zone: zone,
ServerID: ID,
}, scw.WithContext(ctx))

if err != nil && !is404Error(err) {
return diag.FromErr(err)
}

return nil
}
128 changes: 128 additions & 0 deletions scaleway/resource_apple_silicon_server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package scaleway

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
applesilicon "github.com/scaleway/scaleway-sdk-go/api/applesilicon/v1alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func init() {
resource.AddTestSweepers("scaleway_apple_silicon_instance", &resource.Sweeper{
Name: "scaleway_apple_silicon",
F: testSweepAppleSiliconServer,
})
}

func testSweepAppleSiliconServer(_ string) error {
return sweepZones(scw.AllZones, func(scwClient *scw.Client, zone scw.Zone) error {
asAPI := applesilicon.NewAPI(scwClient)
l.Debugf("sweeper: destroying the apple silicon instance in (%s)", zone)
listServers, err := asAPI.ListServers(&applesilicon.ListServersRequest{}, scw.WithAllPages())
if err != nil {
return fmt.Errorf("error listing apple silicon servers in (%s) in sweeper: %s", zone, err)
}

for _, server := range listServers.Servers {
errDelete := asAPI.DeleteServer(&applesilicon.DeleteServerRequest{
ServerID: server.ID,
Zone: zone,
})
if errDelete != nil {
return fmt.Errorf("error deleting apple silicon server in sweeper: %s", err)
}
}

return nil
})
}

func TestAccScalewayAppleSiliconServer_Basic(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayAppleSiliconServerDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource scaleway_apple_silicon_server main {
name = "test-m1"
type = "M1-M"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayAppleSiliconExists(tt, "scaleway_apple_silicon_server.main"),
resource.TestCheckResourceAttr("scaleway_apple_silicon_server.main", "name", "test-m1"),
resource.TestCheckResourceAttr("scaleway_apple_silicon_server.main", "type", "M1-M"),
// Computed
resource.TestCheckResourceAttrSet("scaleway_apple_silicon_server.main", "ip"),
resource.TestCheckResourceAttrSet("scaleway_apple_silicon_server.main", "vnc_url"),
resource.TestCheckResourceAttrSet("scaleway_apple_silicon_server.main", "created_at"),
resource.TestCheckResourceAttrSet("scaleway_apple_silicon_server.main", "deletable_at"),
),
},
},
})
}

func testAccCheckScalewayAppleSiliconExists(tt *TestTools, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("resource not found: %s", n)
}

asAPI, zone, ID, err := asAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

_, err = asAPI.GetServer(&applesilicon.GetServerRequest{
ServerID: ID,
Zone: zone,
})

if err != nil {
return err
}

return nil
}
}

func testAccCheckScalewayAppleSiliconServerDestroy(tt *TestTools) resource.TestCheckFunc {
return func(state *terraform.State) error {
for _, rs := range state.RootModule().Resources {
if rs.Type != "scaleway_apple_silicon_server" {
continue
}

asAPI, zone, ID, err := asAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

_, err = asAPI.GetServer(&applesilicon.GetServerRequest{
ServerID: ID,
Zone: zone,
})

// If no error resource still exist
if err == nil {
return fmt.Errorf("server (%s) still exists", rs.Primary.ID)
}

// Unexpected api error we return it
if !is404Error(err) {
return err
}
}

return nil
}
}
Loading