Skip to content

Commit

Permalink
example
Browse files Browse the repository at this point in the history
  • Loading branch information
mouuii committed Nov 29, 2023
1 parent 61d9baa commit 1f1e570
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 43 deletions.
5 changes: 5 additions & 0 deletions docker_compose/conf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"db_connection": "host=db port=5432 user=postgres password=password dbname=products sslmode=disable",
"bind_address": "0.0.0.0:9090",
"metrics_address": "localhost:9102"
}
20 changes: 20 additions & 0 deletions docker_compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '3.7'
services:
api:
image: "hashicorpdemoapp/product-api:v0.0.22"
ports:
- "19090:9090"
volumes:
- ./conf.json:/config/config.json
environment:
CONFIG_FILE: '/config/config.json'
depends_on:
- db
db:
image: "hashicorpdemoapp/product-api-db:v0.0.22"
ports:
- "15432:5432"
environment:
POSTGRES_DB: 'products'
POSTGRES_USER: 'postgres'
POSTGRES_PASSWORD: 'password'
15 changes: 15 additions & 0 deletions examples/provider-install-verification/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
terraform {
required_providers {
hashicups = {
source = "hashicorp.com/edu/hashicups"
}
}
}

provider "hashicups" {
host = "http://localhost:19090"
username = "education"
password = "test123"
}

data "hashicups_coffees" "example" {}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/hashicorp/terraform-provider-scaffolding-framework
module terraform-provider-hashicups

go 1.19

Expand All @@ -24,6 +24,7 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/hashicorp-demoapp/hashicups-client-go v0.1.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp-demoapp/hashicups-client-go v0.1.0 h1:5eUmjDEqF4viZHLwS9UKSqwDHJ2T9ZQamqSf5dn+qcE=
github.com/hashicorp-demoapp/hashicups-client-go v0.1.0/go.mod h1:fJF8CZhWlImByx49t7RZvuoxskStDwqIWi5/GOSJqGI=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down
25 changes: 25 additions & 0 deletions internal/provider/coffees_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package provider

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
)

func NewCoffeesDataSource() datasource.DataSource {
return &coffeesDataSource{}
}

type coffeesDataSource struct{}

func (d *coffeesDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_coffees"
}

func (d *coffeesDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{}
}

func (d *coffeesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
}
189 changes: 150 additions & 39 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
@@ -1,85 +1,196 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"net/http"
"github.com/hashicorp-demoapp/hashicups-client-go"
"os"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/path"
"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"
)

// Ensure ScaffoldingProvider satisfies various provider interfaces.
var _ provider.Provider = &ScaffoldingProvider{}
// Ensure the implementation satisfies the expected interfaces.
var (
_ provider.Provider = &hashicupsProvider{}
)

// ScaffoldingProvider defines the provider implementation.
type ScaffoldingProvider struct {
// New is a helper function to simplify provider server and testing implementation.
func New(version string) func() provider.Provider {
return func() provider.Provider {
return &hashicupsProvider{
version: version,
}
}
}

// hashicupsProvider is the provider implementation.
type hashicupsProvider struct {
// version is set to the provider version on release, "dev" when the
// provider is built and ran locally, and "test" when running acceptance
// testing.
version string
}

// ScaffoldingProviderModel describes the provider data model.
type ScaffoldingProviderModel struct {
Endpoint types.String `tfsdk:"endpoint"`
}

func (p *ScaffoldingProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "scaffolding"
// Metadata returns the provider type name.
func (p *hashicupsProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "hashicups"
resp.Version = p.version
}

func (p *ScaffoldingProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
// Schema defines the provider-level schema for configuration data.
func (p *hashicupsProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"endpoint": schema.StringAttribute{
MarkdownDescription: "Example provider attribute",
Optional: true,
"host": schema.StringAttribute{
Optional: true,
},
"username": schema.StringAttribute{
Optional: true,
},
"password": schema.StringAttribute{
Optional: true,
Sensitive: true,
},
},
}
}

func (p *ScaffoldingProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
var data ScaffoldingProviderModel
func (p *hashicupsProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
// Retrieve provider data from configuration
var config hashicupsProviderModel
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

// If practitioner provided a configuration value for any of the
// attributes, it must be a known value.

if config.Host.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("host"),
"Unknown HashiCups API Host",
"The provider cannot create the HashiCups API client as there is an unknown configuration value for the HashiCups API host. "+
"Either target apply the source of the value first, set the value statically in the configuration, or use the HASHICUPS_HOST environment variable.",
)
}

if config.Username.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("username"),
"Unknown HashiCups API Username",
"The provider cannot create the HashiCups API client as there is an unknown configuration value for the HashiCups API username. "+
"Either target apply the source of the value first, set the value statically in the configuration, or use the HASHICUPS_USERNAME environment variable.",
)
}

if config.Password.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("password"),
"Unknown HashiCups API Password",
"The provider cannot create the HashiCups API client as there is an unknown configuration value for the HashiCups API password. "+
"Either target apply the source of the value first, set the value statically in the configuration, or use the HASHICUPS_PASSWORD environment variable.",
)
}

if resp.Diagnostics.HasError() {
return
}

// Default values to environment variables, but override
// with Terraform configuration value if set.

host := os.Getenv("HASHICUPS_HOST")
username := os.Getenv("HASHICUPS_USERNAME")
password := os.Getenv("HASHICUPS_PASSWORD")

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if !config.Host.IsNull() {
host = config.Host.ValueString()
}

if !config.Username.IsNull() {
username = config.Username.ValueString()
}

if !config.Password.IsNull() {
password = config.Password.ValueString()
}

// If any of the expected configurations are missing, return
// errors with provider-specific guidance.

if host == "" {
resp.Diagnostics.AddAttributeError(
path.Root("host"),
"Missing HashiCups API Host",
"The provider cannot create the HashiCups API client as there is a missing or empty value for the HashiCups API host. "+
"Set the host value in the configuration or use the HASHICUPS_HOST environment variable. "+
"If either is already set, ensure the value is not empty.",
)
}

if username == "" {
resp.Diagnostics.AddAttributeError(
path.Root("username"),
"Missing HashiCups API Username",
"The provider cannot create the HashiCups API client as there is a missing or empty value for the HashiCups API username. "+
"Set the username value in the configuration or use the HASHICUPS_USERNAME environment variable. "+
"If either is already set, ensure the value is not empty.",
)
}

if password == "" {
resp.Diagnostics.AddAttributeError(
path.Root("password"),
"Missing HashiCups API Password",
"The provider cannot create the HashiCups API client as there is a missing or empty value for the HashiCups API password. "+
"Set the password value in the configuration or use the HASHICUPS_PASSWORD environment variable. "+
"If either is already set, ensure the value is not empty.",
)
}

if resp.Diagnostics.HasError() {
return
}

// Configuration values are now available.
// if data.Endpoint.IsNull() { /* ... */ }
// Create a new HashiCups client using the configuration values
client, err := hashicups.NewClient(&host, &username, &password)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Create HashiCups API Client",
"An unexpected error occurred when creating the HashiCups API client. "+
"If the error is not clear, please contact the provider developers.\n\n"+
"HashiCups Client Error: "+err.Error(),
)
return
}

// Example client configuration for data sources and resources
client := http.DefaultClient
// Make the HashiCups client available during DataSource and Resource
// type Configure methods.
resp.DataSourceData = client
resp.ResourceData = client
}

func (p *ScaffoldingProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewExampleResource,
// DataSources defines the data sources implemented in the provider.
func (p *hashicupsProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewCoffeesDataSource,
}
}

func (p *ScaffoldingProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewExampleDataSource,
}
// Resources defines the resources implemented in the provider.
func (p *hashicupsProvider) Resources(_ context.Context) []func() resource.Resource {
return nil
}

func New(version string) func() provider.Provider {
return func() provider.Provider {
return &ScaffoldingProvider{
version: version,
}
}
// hashicupsProviderModel maps provider schema data to a Go type.
type hashicupsProviderModel struct {
Host types.String `tfsdk:"host"`
Username types.String `tfsdk:"username"`
Password types.String `tfsdk:"password"`
}
11 changes: 8 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"log"

"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-provider-scaffolding-framework/internal/provider"

"terraform-provider-hashicups/internal/provider"
)

// Run "go generate" to format example terraform files and generate the docs for the registry/website
Expand Down Expand Up @@ -38,8 +39,12 @@ func main() {
flag.Parse()

opts := providerserver.ServeOpts{
// TODO: Update this string with the published name of your provider.
Address: "registry.terraform.io/hashicorp/scaffolding",
// NOTE: This is not a typical Terraform Registry provider address,
// such as registry.terraform.io/hashicorp/hashicups. This specific
// provider address is used in these tutorials in conjunction with a
// specific Terraform CLI configuration for manual development testing
// of this provider.
Address: "hashicorp.com/edu/hashicups",
Debug: debug,
}

Expand Down

0 comments on commit 1f1e570

Please sign in to comment.