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

Asb/reorg #1

Merged
merged 7 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Initial reorganization.
  • Loading branch information
andrewsomething committed Feb 3, 2023
commit 48a186e13afce5f01a88ccb4ea531b78b3fbc820
58 changes: 58 additions & 0 deletions digitalocean/acceptance/acceptance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package acceptance

import (
"context"
"fmt"
"os"
"strings"
"testing"

"github.com/digitalocean/terraform-provider-digitalocean/digitalocean"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

const TestNamePrefix = "tf-acc-test-"

var (
TestAccProvider *schema.Provider
TestAccProviders map[string]*schema.Provider
TestAccProviderFactories map[string]func() (*schema.Provider, error)
)

func init() {
TestAccProvider = digitalocean.Provider()
TestAccProviders = map[string]*schema.Provider{
"digitalocean": TestAccProvider,
}
TestAccProviderFactories = map[string]func() (*schema.Provider, error){
"digitalocean": func() (*schema.Provider, error) {
return TestAccProvider, nil
},
}
}

func TestAccPreCheck(t *testing.T) {
if v := os.Getenv("DIGITALOCEAN_TOKEN"); v == "" {
t.Fatal("DIGITALOCEAN_TOKEN must be set for acceptance tests")
}

err := TestAccProvider.Configure(context.Background(), terraform.NewResourceConfigRaw(nil))
if err != nil {
t.Fatal(err)
}
}

func RandomTestName(additionalNames ...string) string {
prefix := TestNamePrefix
for _, n := range additionalNames {
prefix += "-" + strings.Replace(n, " ", "_", -1)
}
return randomName(prefix, 10)
}

func randomName(prefix string, length int) string {
return fmt.Sprintf("%s%s", prefix, acctest.RandString(length))
}
88 changes: 88 additions & 0 deletions digitalocean/acceptance/certs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package acceptance

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"strings"
"testing"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
)

func GenerateTestCertMaterial(t *testing.T) (string, string, string) {
leafCertMaterial, privateKeyMaterial, err := randTLSCert("Acme Co", "example.com")
if err != nil {
t.Fatalf("Cannot generate test TLS certificate: %s", err)
}
rootCertMaterial, _, err := randTLSCert("Acme Go", "example.com")
if err != nil {
t.Fatalf("Cannot generate test TLS certificate: %s", err)
}
certChainMaterial := fmt.Sprintf("%s\n%s", strings.TrimSpace(rootCertMaterial), leafCertMaterial)

return privateKeyMaterial, leafCertMaterial, certChainMaterial
}

// Based on Terraform's acctest.RandTLSCert, but allows for passing DNS name.
func randTLSCert(orgName string, dnsName string) (string, string, error) {
template := &x509.Certificate{
SerialNumber: big.NewInt(int64(acctest.RandInt())),
Subject: pkix.Name{
Organization: []string{orgName},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{dnsName},
}

privateKey, privateKeyPEM, err := genPrivateKey()
if err != nil {
return "", "", err
}

cert, err := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey)
if err != nil {
return "", "", err
}

certPEM, err := pemEncode(cert, "CERTIFICATE")
if err != nil {
return "", "", err
}

return certPEM, privateKeyPEM, nil
}

func genPrivateKey() (*rsa.PrivateKey, string, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, "", err
}

privateKeyPEM, err := pemEncode(x509.MarshalPKCS1PrivateKey(privateKey), "RSA PRIVATE KEY")
if err != nil {
return nil, "", err
}

return privateKey, privateKeyPEM, nil
}

func pemEncode(b []byte, block string) (string, error) {
var buf bytes.Buffer
pb := &pem.Block{Type: block, Bytes: b}
if err := pem.Encode(&buf, pb); err != nil {
return "", err
}

return buf.String(), nil
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package digitalocean
package acceptance

import (
"fmt"
"os"
"testing"

"github.com/digitalocean/terraform-provider-digitalocean/digitalocean/config"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestMain(m *testing.M) {
resource.TestMain(m)
}

func sharedConfigForRegion(region string) (interface{}, error) {
func SharedConfigForRegion(region string) (interface{}, error) {
if os.Getenv("DIGITALOCEAN_TOKEN") == "" {
return nil, fmt.Errorf("empty DIGITALOCEAN_TOKEN")
}
Expand All @@ -27,14 +28,14 @@ func sharedConfigForRegion(region string) (interface{}, error) {
spacesEndpoint = "https://{{.Region}}.digitaloceanspaces.com"
}

config := Config{
conf := config.Config{
Token: os.Getenv("DIGITALOCEAN_TOKEN"),
APIEndpoint: apiEndpoint,
SpacesAPIEndpoint: spacesEndpoint,
}

// configures a default client for the region, using the above env vars
client, err := config.Client()
client, err := conf.Client()
if err != nil {
return nil, fmt.Errorf("error getting DigitalOcean client")
}
Expand Down
152 changes: 152 additions & 0 deletions digitalocean/acceptance/test_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package acceptance

import (
"context"
"fmt"
"log"
"strconv"
"strings"

"github.com/digitalocean/godo"
"github.com/digitalocean/terraform-provider-digitalocean/digitalocean/config"
"github.com/digitalocean/terraform-provider-digitalocean/digitalocean/util"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestResourceInstanceState(name string, check func(*terraform.InstanceState) error) resource.TestCheckFunc {
return func(s *terraform.State) error {
m := s.RootModule()
if rs, ok := m.Resources[name]; ok {
is := rs.Primary
if is == nil {
return fmt.Errorf("No primary instance: %s", name)
}

return check(is)
} else {
return fmt.Errorf("Not found: %s", name)
}

}
}

func TestAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
client := TestAccProvider.Meta().(*config.CombinedConfig).GodoClient()

for _, rs := range s.RootModule().Resources {
if rs.Type != "digitalocean_droplet" {
continue
}

id, err := strconv.Atoi(rs.Primary.ID)
if err != nil {
return err
}

// Try to find the Droplet
_, _, err = client.Droplets.Get(context.Background(), id)

// Wait

if err != nil && !strings.Contains(err.Error(), "404") {
return fmt.Errorf(
"Error waiting for droplet (%s) to be destroyed: %s",
rs.Primary.ID, err)
}
}

return nil
}

func TestAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No Droplet ID is set")
}

client := TestAccProvider.Meta().(*config.CombinedConfig).GodoClient()

id, err := strconv.Atoi(rs.Primary.ID)
if err != nil {
return err
}

// Try to find the Droplet
retrieveDroplet, _, err := client.Droplets.Get(context.Background(), id)

if err != nil {
return err
}

if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID {
return fmt.Errorf("Droplet not found")
}

*droplet = *retrieveDroplet

return nil
}
}

func TestAccCheckDigitalOceanDropletConfig_basic(rInt int) string {
return fmt.Sprintf(`
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
}`, rInt)
}

func TakeSnapshotsOfDroplet(rInt int, droplet *godo.Droplet, snapshotsId *[]int) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := TestAccProvider.Meta().(*config.CombinedConfig).GodoClient()
for i := 0; i < 3; i++ {
err := takeSnapshotOfDroplet(rInt, i%2, droplet)
if err != nil {
return err
}
}
retrieveDroplet, _, err := client.Droplets.Get(context.Background(), (*droplet).ID)
if err != nil {
return err
}
*snapshotsId = retrieveDroplet.SnapshotIDs
return nil
}
}

func takeSnapshotOfDroplet(rInt, sInt int, droplet *godo.Droplet) error {
client := TestAccProvider.Meta().(*config.CombinedConfig).GodoClient()
action, _, err := client.DropletActions.Snapshot(context.Background(), (*droplet).ID, fmt.Sprintf("snap-%d-%d", rInt, sInt))
if err != nil {
return err
}
util.WaitForAction(client, action)
return nil
}

func DeleteDropletSnapshots(snapshotsId *[]int) resource.TestCheckFunc {
return func(s *terraform.State) error {
log.Printf("Deleting Droplet snapshots")

client := TestAccProvider.Meta().(*config.CombinedConfig).GodoClient()

snapshots := *snapshotsId
for _, value := range snapshots {
log.Printf("Deleting %d", value)
_, err := client.Images.Delete(context.Background(), value)
if err != nil {
return err
}
}
return nil
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package digitalocean
package account

import (
"context"

"github.com/digitalocean/terraform-provider-digitalocean/digitalocean/config"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceDigitalOceanAccount() *schema.Resource {
func DataSourceDigitalOceanAccount() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceDigitalOceanAccountRead,
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -51,7 +53,7 @@ func dataSourceDigitalOceanAccount() *schema.Resource {
}

func dataSourceDigitalOceanAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*CombinedConfig).godoClient()
client := meta.(*config.CombinedConfig).GodoClient()

account, _, err := client.Account.Get(context.Background())
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package digitalocean
package account_test

import (
"fmt"
"testing"

"github.com/digitalocean/terraform-provider-digitalocean/digitalocean/acceptance"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceDigitalOceanAccount_Basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
PreCheck: func() { acceptance.TestAccPreCheck(t) },
ProviderFactories: acceptance.TestAccProviderFactories,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(testAccCheckDataSourceDigitalOceanAccountConfig_basic),
Expand Down
2 changes: 1 addition & 1 deletion digitalocean/app_spec.go → digitalocean/app/app_spec.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package digitalocean
package app

import (
"log"
Expand Down
Loading