Skip to content

Commit

Permalink
Package reorganization (#927)
Browse files Browse the repository at this point in the history
* Initial reorganization.

* Update Makefile for running accepance tests under new organization.

* Update sweepers for new organization.

* Remove unused functions from util package.

* godo.PtrTo replaces the boolPtr and intPtr helpers.

* Clean up util package.

* Reorg helpers in acceptance package.
  • Loading branch information
andrewsomething committed Feb 7, 2023
1 parent 96ba57d commit 95da01c
Show file tree
Hide file tree
Showing 231 changed files with 3,147 additions and 2,832 deletions.
16 changes: 5 additions & 11 deletions GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
TEST?=$$(go list ./... |grep -v 'vendor')
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
PKG_NAME=digitalocean
PKG_NAME:=digitalocean
ACCTEST_TIMEOUT:=120m
ACCTEST_PARALLELISM:=2

default: build

Expand All @@ -13,7 +15,7 @@ test: fmtcheck
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4

testacc: fmtcheck
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
TF_ACC=1 go test -v ./$(PKG_NAME)/... $(TESTARGS) -timeout $(ACCTEST_TIMEOUT) -parallel=$(ACCTEST_PARALLELISM)

vet:
@echo "go vet ."
Expand All @@ -26,7 +28,7 @@ vet:

sweep:
@echo "WARNING: This will destroy infrastructure. Use only in development accounts."
go test ./digitalocean -v -sweep=1
go test ./digitalocean/sweep/... -v -sweep=1

goimports:
@echo "==> Fixing imports code with goimports..."
Expand All @@ -47,14 +49,6 @@ fmtcheck:
errcheck:
@sh -c "'$(CURDIR)/scripts/errcheck.sh'"

test-compile:
@if [ "$(TEST)" = "./..." ]; then \
echo "ERROR: Set TEST to a specific package. For example,"; \
echo " make test-compile TEST=./$(PKG_NAME)"; \
exit 1; \
fi
go test -c $(TEST) $(TESTARGS)

website:
@echo "Use this site to preview markdown rendering: https://registry.terraform.io/tools/doc-preview"

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ In order to run a specific acceptance test, use the `TESTARGS` environment varia
$ make testacc TESTARGS='-run=TestAccDigitalOceanDomain_Basic'
```

All acceptance tests for a specific package can be run by setting the `PKG_NAME` environment variable. For example:

```sh
$ make testacc PKG_NAME=digitalocean/account
```

In order to check changes you made locally to the provider, you can use the binary you just compiled by adding the following
to your `~/.terraformrc` file. This is valid for Terraform 0.14+. Please see
[Terraform's documentation](https://www.terraform.io/docs/cli/config/config-file.html#development-overrides-for-provider-developers)
Expand Down Expand Up @@ -111,7 +117,7 @@ To release the provider:
git tag -m "release $new_version" -a "$new_version"
```

1. Push the tag:
1. Push the tag:

```bash
git push "$origin" tag "$new_version"
Expand Down
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))
}
89 changes: 89 additions & 0 deletions digitalocean/acceptance/certs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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"
)

// GenerateTestCertMaterial generates a TLS certificate for use in acceptance test fixtures.
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
}
135 changes: 135 additions & 0 deletions digitalocean/acceptance/droplets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
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 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,4 +1,4 @@
package digitalocean
package acceptance

import (
"fmt"
Expand All @@ -7,7 +7,9 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func testResourceInstanceState(name string, check func(*terraform.InstanceState) error) resource.TestCheckFunc {
// TestResourceInstanceState is a resource.TestCheckFunc to test if a resource is
// present in the instance state.
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 {
Expand Down
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

0 comments on commit 95da01c

Please sign in to comment.