Skip to content

Commit

Permalink
chore(sdk): Implement skeleton of provider in the framework plugin
Browse files Browse the repository at this point in the history
This combined with the muxing will allow us to migrate resources and datasources one at a time
  • Loading branch information
tete17 committed Aug 19, 2024
1 parent e96137e commit 71f5ff1
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 17 deletions.
122 changes: 108 additions & 14 deletions cloudamqp/provider.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,136 @@
package cloudamqp

import (
"context"
"fmt"
"log"
"net/http"
"os"

"github.com/cloudamqp/terraform-provider-cloudamqp/api"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
schemaSdk "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var version string
var enableFasterInstanceDestroy bool

func Provider(v string, client *http.Client) *schema.Provider {
type cloudamqpProvider struct {
version string
client *http.Client
}

type cloudamqpProviderModel struct {
ApiKey types.String `tfsdk:"apikey"`
BaseUrl types.String `tfsdk:"baseurl"`
EnableFasterInstanceDestroy types.Bool `tfsdk:"enable_faster_instance_destroy"`
}

func (p *cloudamqpProvider) Metadata(_ context.Context, _ provider.MetadataRequest, response *provider.MetadataResponse) {
response.Version = p.version
response.TypeName = "cloudamqp"
}

func (p *cloudamqpProvider) Schema(_ context.Context, _ provider.SchemaRequest, response *provider.SchemaResponse) {
response.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"apikey": schema.StringAttribute{
Optional: true,
Description: "Key used to authentication to the CloudAMQP Customer API",
},
"baseurl": schema.StringAttribute{
Optional: true,
Description: "Base URL to CloudAMQP Customer website",
},
"enable_faster_instance_destroy": schema.BoolAttribute{
Optional: true,
Description: "Skips destroying backend resources on 'terraform destroy'",
},
},
}
}

func (p *cloudamqpProvider) Configure(ctx context.Context, request provider.ConfigureRequest, response *provider.ConfigureResponse) {
var data cloudamqpProviderModel

// Read configuration data into model
response.Diagnostics.Append(request.Config.Get(ctx, &data)...)

apiKey := data.ApiKey.ValueString()
baseUrl := data.BaseUrl.ValueString()

// Check configuration data, which should take precedence over
// environment variable data, if found.
if apiKey == "" {
apiKey = os.Getenv("CLOUDAMQP_APIKEY")
}

if apiKey == "" {
response.Diagnostics.AddError(
"Missing API Key Configuration",
"While configuring the provider, the API key was not found in "+
"the CLOUDAMQP_APIKEY environment variable or provider "+
"configuration block apikey attribute.",
)
}

if baseUrl == "" {
baseUrl = os.Getenv("CLOUDAMQP_BASEURL")
}

if baseUrl == "" {
baseUrl = "https://customer.cloudamqp.com"
}

useragent := fmt.Sprintf("terraform-provider-cloudamqp_v%s", p.version)
log.Printf("[DEBUG] cloudamqp::provider::configure useragent: %v", useragent)
apiClient := api.New(baseUrl, apiKey, useragent, p.client)

response.ResourceData = apiClient
response.DataSourceData = apiClient
}

func (p *cloudamqpProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{}
}

func (p *cloudamqpProvider) Resources(_ context.Context) []func() resource.Resource {
return []func() resource.Resource{}
}

func New(version string, client *http.Client) provider.Provider {
return &cloudamqpProvider{version, client}
}

func Provider(v string, client *http.Client) *schemaSdk.Provider {
version = v
log.Printf("Terraform-Provider-CloudAMQP Version: %s", version)
return &schema.Provider{
Schema: map[string]*schema.Schema{
return &schemaSdk.Provider{
Schema: map[string]*schemaSdk.Schema{
"apikey": {
Type: schema.TypeString,
Type: schemaSdk.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("CLOUDAMQP_APIKEY", nil),
DefaultFunc: schemaSdk.EnvDefaultFunc("CLOUDAMQP_APIKEY", nil),
Description: "Key used to authentication to the CloudAMQP Customer API",
},
"baseurl": {
Type: schema.TypeString,
DefaultFunc: schema.EnvDefaultFunc("CLOUDAMQP_BASEURL", "https://customer.cloudamqp.com"),
Type: schemaSdk.TypeString,
DefaultFunc: schemaSdk.EnvDefaultFunc("CLOUDAMQP_BASEURL", "https://customer.cloudamqp.com"),
Optional: true,
Description: "Base URL to CloudAMQP Customer website",
},
"enable_faster_instance_destroy": {
Type: schema.TypeBool,
DefaultFunc: schema.EnvDefaultFunc("CLOUDAMQP_ENABLE_FASTER_INSTANCE_DESTROY", false),
Type: schemaSdk.TypeBool,
DefaultFunc: schemaSdk.EnvDefaultFunc("CLOUDAMQP_ENABLE_FASTER_INSTANCE_DESTROY", false),
Optional: true,
Description: "Skips destroying backend resources on 'terraform destroy'",
},
},
DataSourcesMap: map[string]*schema.Resource{
DataSourcesMap: map[string]*schemaSdk.Resource{
"cloudamqp_account_vpcs": dataSourceAccountVpcs(),
"cloudamqp_account": dataSourceAccount(),
"cloudamqp_alarm": dataSourceAlarm(),
Expand All @@ -50,7 +144,7 @@ func Provider(v string, client *http.Client) *schema.Provider {
"cloudamqp_vpc_gcp_info": dataSourceVpcGcpInfo(),
"cloudamqp_vpc_info": dataSourceVpcInfo(),
},
ResourcesMap: map[string]*schema.Resource{
ResourcesMap: map[string]*schemaSdk.Resource{
"cloudamqp_account_action": resourceAccountAction(),
"cloudamqp_alarm": resourceAlarm(),
"cloudamqp_custom_domain": resourceCustomDomain(),
Expand Down Expand Up @@ -78,8 +172,8 @@ func Provider(v string, client *http.Client) *schema.Provider {
}
}

func configureClient(client *http.Client) schema.ConfigureFunc {
return func(d *schema.ResourceData) (interface{}, error) {
func configureClient(client *http.Client) schemaSdk.ConfigureFunc {
return func(d *schemaSdk.ResourceData) (interface{}, error) {
enableFasterInstanceDestroy = d.Get("enable_faster_instance_destroy").(bool)
useragent := fmt.Sprintf("terraform-provider-cloudamqp_v%s", version)
log.Printf("[DEBUG] cloudamqp::provider::configure useragent: %v", useragent)
Expand Down
6 changes: 5 additions & 1 deletion cloudamqp/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"testing"

"github.com/cloudamqp/terraform-provider-cloudamqp/cloudamqp/vcr-testing/sanitizer"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-mux/tf5muxserver"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand Down Expand Up @@ -159,7 +160,10 @@ func cloudamqpResourceTest(t *testing.T, c resource.TestCase) {
"cloudamqp": func() (tfprotov5.ProviderServer, error) {
ctx := context.Background()

muxServer, err := tf5muxserver.NewMuxServer(ctx, Provider("1.0", rec.GetDefaultClient()).GRPCProvider)
muxServer, err := tf5muxserver.NewMuxServer(ctx,
Provider("1.0", rec.GetDefaultClient()).GRPCProvider,
providerserver.NewProtocol5(New("1.0", rec.GetDefaultClient())),
)

if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ toolchain go1.22.2

require (
github.com/dghubble/sling v1.4.2
github.com/hashicorp/terraform-plugin-framework v1.9.0
github.com/hashicorp/terraform-plugin-go v0.23.0
github.com/hashicorp/terraform-plugin-mux v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
Expand All @@ -19,7 +20,6 @@ require (
github.com/agext/levenshtein v1.2.2 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/dghubble/sling v1.4.2 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8J
github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw=
github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U=
github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
github.com/hashicorp/terraform-plugin-framework v1.8.0 h1:P07qy8RKLcoBkCrY2RHJer5AEvJnDuXomBgou6fD8kI=
github.com/hashicorp/terraform-plugin-framework v1.8.0/go.mod h1:/CpTukO88PcL/62noU7cuyaSJ4Rsim+A/pa+3rUVufY=
github.com/hashicorp/terraform-plugin-framework v1.9.0 h1:caLcDoxiRucNi2hk8+j3kJwkKfvHznubyFsJMWfZqKU=
github.com/hashicorp/terraform-plugin-framework v1.9.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM=
github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co=
github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
Expand Down
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/cloudamqp/terraform-provider-cloudamqp/cloudamqp"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server"
"github.com/hashicorp/terraform-plugin-mux/tf5muxserver"
)
Expand All @@ -15,7 +16,10 @@ var version string
func main() {
ctx := context.Background()

muxServer, err := tf5muxserver.NewMuxServer(ctx, cloudamqp.Provider(version, http.DefaultClient).GRPCProvider)
muxServer, err := tf5muxserver.NewMuxServer(
ctx, cloudamqp.Provider(version, http.DefaultClient).GRPCProvider,
providerserver.NewProtocol5(cloudamqp.New(version, http.DefaultClient)),
)

if err != nil {
log.Fatal(err)
Expand Down

0 comments on commit 71f5ff1

Please sign in to comment.