internal/provider/apikeys_data_source.go (153 lines of code) (raw):

// Copyright (c) HashiCorp, Inc. package provider import ( "context" "fmt" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "terraform-provider-devlake/internal/client" ) // Ensure the implementation satisfies the expected interfaces. var ( _ datasource.DataSource = &apiKeysDataSource{} _ datasource.DataSourceWithConfigure = &apiKeysDataSource{} ) // NewApiKeysDataSource is a helper function to simplify the provider implementation. func NewApiKeysDataSource() datasource.DataSource { return &apiKeysDataSource{} } // apiKeysDataSource is the data source implementation. type apiKeysDataSource struct { client *client.Client } // apiKeysDataSourceModel maps the data source schema data. type apiKeysDataSourceModel struct { ApiKeys []apiKeysModel `tfsdk:"apikeys"` } // apiKeysModel maps apiKeys schema data. type apiKeysModel struct { ID types.Int64 `tfsdk:"id"` AllowedPath types.String `tfsdk:"allowed_path"` ApiKey types.String `tfsdk:"api_key"` CreatedAt types.String `tfsdk:"created_at"` Creator types.String `tfsdk:"creator"` CreatorEmail types.String `tfsdk:"creator_email"` ExpiredAt types.String `tfsdk:"expired_at"` Extra types.String `tfsdk:"extra"` Name types.String `tfsdk:"name"` Type types.String `tfsdk:"type"` UpdatedAt types.String `tfsdk:"updated_at"` Updater types.String `tfsdk:"updater"` UpdaterEmail types.String `tfsdk:"updater_email"` } // Metadata returns the data source type name. func (d *apiKeysDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_apikeys" } // Schema defines the schema for the data source. func (d *apiKeysDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "apikeys": schema.ListNestedAttribute{ Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "id": schema.Int64Attribute{ Computed: true, Description: "Numeric identifier for the apikey.", }, "allowed_path": schema.StringAttribute{ Computed: true, Description: "The API URL or endpoint that the API key is permitted to access. It defines the specific resources that the key can interact with.", }, "api_key": schema.StringAttribute{ Computed: true, Description: "The returned apikey, will always be empty for security reasons. If you want to use the apikey, you need to create a new resource.", }, "created_at": schema.StringAttribute{ Computed: true, Description: "When the apikey was created.", }, "creator": schema.StringAttribute{ Computed: true, Description: "Who created the apikey, there is no user management yet though.", }, "creator_email": schema.StringAttribute{ Computed: true, Description: "Email of the person who created the apikey, there is no user management yet though.", }, "expired_at": schema.StringAttribute{ Computed: true, Description: "When the apikey expires.", }, "extra": schema.StringAttribute{ Computed: true, Description: "Currently not used.", }, "name": schema.StringAttribute{ Computed: true, Description: "The name of the apikey.", }, "type": schema.StringAttribute{ Computed: true, Description: "The apikey type. Currently only 'devlake' is a valid value.", }, "updated_at": schema.StringAttribute{ Computed: true, Description: "When the apikey was last updated. Serves no purpose as the UPDATE endpoint doesn't do anything.", }, "updater": schema.StringAttribute{ Computed: true, Description: "Who updated the apikey, there is no user management yet though.", }, "updater_email": schema.StringAttribute{ Computed: true, Description: "Email of the person who updated the apikey, there is no user management yet though.", }, }, }, }, }, } } // Read refreshes the Terraform state with the latest data. func (d *apiKeysDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { var state apiKeysDataSourceModel apiKeys, err := d.client.GetApiKeys() if err != nil { resp.Diagnostics.AddError( "Unable to Read Devlake ApiKeys", err.Error(), ) return } // Map response body to model for _, apiKey := range apiKeys { apiKeyState := apiKeysModel{ ID: types.Int64Value(int64(apiKey.ID)), AllowedPath: types.StringValue(apiKey.AllowedPath), ApiKey: types.StringValue(apiKey.ApiKey), CreatedAt: types.StringValue(apiKey.CreatedAt), Creator: types.StringValue(apiKey.Creator), CreatorEmail: types.StringValue(apiKey.CreatorEmail), ExpiredAt: types.StringValue(apiKey.ExpiredAt), Extra: types.StringValue(apiKey.Extra), Name: types.StringValue(apiKey.Name), Type: types.StringValue(apiKey.Type), UpdatedAt: types.StringValue(apiKey.UpdatedAt), Updater: types.StringValue(apiKey.Updater), UpdaterEmail: types.StringValue(apiKey.UpdaterEmail), } state.ApiKeys = append(state.ApiKeys, apiKeyState) } // Set state diags := resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } } // Configure adds the provider configured client to the data source. func (d *apiKeysDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { // Add a nil check when handling ProviderData because Terraform // sets that data after it calls the ConfigureProvider RPC. if req.ProviderData == nil { return } client, ok := req.ProviderData.(*client.Client) if !ok { resp.Diagnostics.AddError( "Unexpected Data Source Configure Type", fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), ) return } d.client = client }