// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package provider import ( "context" "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" "net/http" "net/url" "os" ) // Ensure ScaffoldingProvider satisfies various provider interfaces. var _ provider.Provider = &ScaffoldingProvider{} // ScaffoldingProvider defines the provider implementation. type ScaffoldingProvider 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"` ApiToken types.String `tfsdk:"api_token"` } func (p *ScaffoldingProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { resp.TypeName = "virtfusion" resp.Version = p.version } func (p *ScaffoldingProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "endpoint": schema.StringAttribute{ MarkdownDescription: "The endpoint to use for API requests.", Required: true, }, "api_token": schema.StringAttribute{ MarkdownDescription: "The API token to use for API requests.", Required: true, }, }, } } func (p *ScaffoldingProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { // Check environment variables apiToken := os.Getenv("VIRTFUSION_API_TOKEN") endpoint := os.Getenv("VIRTFUSION_ENDPOINT") var data ScaffoldingProviderModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } // Configuration values are now available. // if data.Endpoint.IsNull() { /* ... */ } if data.Endpoint.ValueString() != "" { endpoint = data.Endpoint.ValueString() } if data.ApiToken.ValueString() != "" { apiToken = data.ApiToken.ValueString() } if apiToken == "" { resp.Diagnostics.AddError( "Missing API Token Configuration", "While configuring the provider, the API token was not found in "+ "the VIRTFUSION_API_TOKEN environment variable or provider "+ "configuration block api_token attribute.", ) // Not returning early allows the logic to collect all errors. } if endpoint == "" { resp.Diagnostics.AddError( "Missing Endpoint Configuration", "While configuring the provider, the endpoint was not found in "+ "the VIRTFUSION_ENDPOINT environment variable or provider "+ "configuration block endpoint attribute.", ) // Not returning early allows the logic to collect all errors. } customTransport := &CustomTransport{ Transport: http.DefaultTransport, BaseURL: &url.URL{Scheme: "https", Host: endpoint + "/api/v1"}, Token: apiToken, } // Example client configuration for data sources and resources client := &http.Client{ Transport: customTransport, } resp.DataSourceData = client resp.ResourceData = client } func (p *ScaffoldingProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ NewVirtfusionServerResource, } } func (p *ScaffoldingProvider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ NewVirtfusionDataSource, } } type CustomTransport struct { Transport http.RoundTripper BaseURL *url.URL Token string } func (c *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Add("Authorization", "Bearer "+c.Token) req.URL.Scheme = c.BaseURL.Scheme req.URL.Host = c.BaseURL.Host req.URL.Path = c.BaseURL.Path + req.URL.Path return c.Transport.RoundTrip(req) } func New(version string) func() provider.Provider { return func() provider.Provider { return &ScaffoldingProvider{ version: version, } } }