// Copyright (c) EZSCALE. // SPDX-License-Identifier: MPL-2.0 package provider import ( "context" "fmt" "os" "terraform-provider-virtfusion/internal/client" "github.com/hashicorp/terraform-plugin-framework/datasource" dsschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "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" ) const defaultResultsPerPage int64 = 300 // resultsSchemaAttribute returns the standard "results" schema attribute for list data sources. func resultsSchemaAttribute() dsschema.Int64Attribute { return dsschema.Int64Attribute{ MarkdownDescription: "Maximum number of results to return. Defaults to 300.", Optional: true, } } // resultsQueryParam returns the query parameter string for the results limit. // If results is null/unknown, defaults to defaultResultsPerPage. func resultsQueryParam(results types.Int64) string { n := defaultResultsPerPage if !results.IsNull() && !results.IsUnknown() { n = results.ValueInt64() } return fmt.Sprintf("results=%d", n) } var _ provider.Provider = &VirtfusionProvider{} // VirtfusionProvider defines the provider implementation. type VirtfusionProvider struct { version string } // VirtfusionProviderModel describes the provider data model. type VirtfusionProviderModel struct { Endpoint types.String `tfsdk:"endpoint"` ApiToken types.String `tfsdk:"api_token"` } func (p *VirtfusionProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) { resp.TypeName = "virtfusion" resp.Version = p.version } func (p *VirtfusionProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) { resp.Schema = schema.Schema{ MarkdownDescription: "The VirtFusion provider allows managing VirtFusion virtualization platform resources.", Attributes: map[string]schema.Attribute{ "endpoint": schema.StringAttribute{ MarkdownDescription: "The VirtFusion API endpoint. Can be a hostname (e.g. `cp.example.com`) or full URL (e.g. `https://cp.example.com/api/v1`). Can also be set with the `VIRTFUSION_ENDPOINT` environment variable.", Optional: true, }, "api_token": schema.StringAttribute{ MarkdownDescription: "The API token for authentication. Can also be set with the `VIRTFUSION_API_TOKEN` environment variable.", Optional: true, Sensitive: true, }, }, } } func (p *VirtfusionProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { var data VirtfusionProviderModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } // Environment variables as fallback endpoint := os.Getenv("VIRTFUSION_ENDPOINT") apiToken := os.Getenv("VIRTFUSION_API_TOKEN") // Config values override env vars if !data.Endpoint.IsNull() && data.Endpoint.ValueString() != "" { endpoint = data.Endpoint.ValueString() } if !data.ApiToken.IsNull() && data.ApiToken.ValueString() != "" { apiToken = data.ApiToken.ValueString() } if endpoint == "" { resp.Diagnostics.AddError( "Missing Endpoint Configuration", "The VirtFusion endpoint was not found in the VIRTFUSION_ENDPOINT environment variable or provider configuration block endpoint attribute.", ) } if apiToken == "" { resp.Diagnostics.AddError( "Missing API Token Configuration", "The API token was not found in the VIRTFUSION_API_TOKEN environment variable or provider configuration block api_token attribute.", ) } if resp.Diagnostics.HasError() { return } c, err := client.New(endpoint, apiToken) if err != nil { resp.Diagnostics.AddError("Failed to Create Client", err.Error()) return } resp.DataSourceData = c resp.ResourceData = c } func (p *VirtfusionProvider) Resources(_ context.Context) []func() resource.Resource { return []func() resource.Resource{ NewServerResource, NewServerBuildResource, NewSSHKeyResource, NewUserResource, NewServerFirewallResource, NewServerNetworkWhitelistResource, NewServerIPv4Resource, NewServerTrafficBlockResource, NewIPBlockRangeResource, NewSelfServiceCreditResource, NewSelfServiceResourcePackResource, NewSelfServiceHourlyGroupProfileResource, NewSelfServiceResourceGroupProfileResource, NewServerPowerActionResource, NewServerPasswordResetResource, NewUserPasswordResetResource, NewUserAuthTokenResource, NewUserServerAuthTokenResource, NewSelfServicePackServersActionResource, NewSelfServiceHourlyResourcePackResource, } } func (p *VirtfusionProvider) DataSources(_ context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ NewHypervisorDataSource, NewHypervisorsDataSource, NewHypervisorGroupDataSource, NewHypervisorGroupsDataSource, NewHypervisorGroupResourcesDataSource, NewServerDataSource, NewServersDataSource, NewServersByUserDataSource, NewServerTemplatesDataSource, NewServerTrafficDataSource, NewServerTrafficBlocksDataSource, NewServerVNCDataSource, NewServerBackupsDataSource, NewServerFirewallDataSource, NewPackageDataSource, NewPackagesDataSource, NewPackageTemplatesDataSource, NewIPBlockDataSource, NewIPBlocksDataSource, NewSSHKeyDataSource, NewSSHKeysByUserDataSource, NewUserDataSource, NewDNSServiceDataSource, NewISODataSource, NewQueueItemDataSource, NewSelfServiceCurrenciesDataSource, NewSelfServiceResourcePackDataSource, NewSelfServiceHourlyStatsDataSource, NewSelfServiceReportDataSource, NewSelfServiceUsageDataSource, } } func New(version string) func() provider.Provider { return func() provider.Provider { return &VirtfusionProvider{ version: version, } } }