332 lines
13 KiB
Go
332 lines
13 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"git.adyxax.org/adyxax/terraform-provider-eventline/external/evcli"
|
|
"github.com/exograd/go-daemon/ksuid"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
)
|
|
|
|
type JobsDataSource struct {
|
|
client *evcli.Client
|
|
}
|
|
|
|
var _ datasource.DataSource = &JobsDataSource{} // Ensure provider defined types fully satisfy framework interfaces
|
|
func NewJobsDataSource() datasource.DataSource {
|
|
return &JobsDataSource{}
|
|
}
|
|
|
|
type JobsDataSourceModel struct {
|
|
Elements []JobDataSourceModel `tfsdk:"elements"`
|
|
ProjectId types.String `tfsdk:"project_id"`
|
|
}
|
|
type JobDataSourceModel struct {
|
|
Disabled types.Bool `tfsdk:"disabled"`
|
|
Id types.String `tfsdk:"id"`
|
|
Spec JobSpecDataSourceModel `tfsdk:"spec"`
|
|
}
|
|
type JobSpecDataSourceModel struct {
|
|
Concurrent types.Bool `tfsdk:"concurrent"`
|
|
Description types.String `tfsdk:"description"`
|
|
Environment types.Map `tfsdk:"environment"`
|
|
Identities types.Set `tfsdk:"identities"`
|
|
Name types.String `tfsdk:"name"`
|
|
Parameters []ParameterDataSourceModel `tfsdk:"parameters"`
|
|
Retention types.Int64 `tfsdk:"retention"`
|
|
Runner *RunnerDataSourceModel `tfsdk:"runner"`
|
|
Trigger *TriggerDataSourceModel `tfsdk:"trigger"`
|
|
Steps []StepDataSourceModel `tfsdk:"steps"`
|
|
}
|
|
type ParameterDataSourceModel struct {
|
|
Description types.String `tfsdk:"description"`
|
|
Environment types.String `tfsdk:"environment"`
|
|
Name types.String `tfsdk:"name"`
|
|
Type types.String `tfsdk:"type"`
|
|
Values types.List `tfsdk:"values"`
|
|
}
|
|
type RunnerDataSourceModel struct {
|
|
Name types.String `tfsdk:"name"`
|
|
Identity types.String `tfsdk:"identity"`
|
|
}
|
|
type StepDataSourceModel struct {
|
|
Code types.String `tfsdk:"code"`
|
|
Command *StepCommandDataSourceModel `tfsdk:"command"`
|
|
Label types.String `tfsdk:"label"`
|
|
Script *StepScriptDataSourceModel `tfsdk:"script"`
|
|
}
|
|
type StepCommandDataSourceModel struct {
|
|
Arguments types.List `tfsdk:"arguments"`
|
|
Name types.String `tfsdk:"name"`
|
|
}
|
|
type StepScriptDataSourceModel struct {
|
|
Arguments types.List `tfsdk:"arguments"`
|
|
Content types.String `tfsdk:"content"`
|
|
Path types.String `tfsdk:"path"`
|
|
}
|
|
type TriggerDataSourceModel struct {
|
|
Event types.String `tfsdk:"event"`
|
|
Identity types.String `tfsdk:"identity"`
|
|
}
|
|
|
|
func (d *JobsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
|
resp.TypeName = req.ProviderTypeName + "_jobs"
|
|
}
|
|
|
|
func (d *JobsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Attributes: map[string]schema.Attribute{
|
|
"elements": schema.ListNestedAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The list of jobs.",
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: map[string]schema.Attribute{
|
|
"disabled": schema.BoolAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "Whether the job is disabled or not.",
|
|
},
|
|
"id": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The identifier of the job.",
|
|
},
|
|
"spec": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"concurrent": schema.BoolAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "Whether to allow concurrent executions for this job or not.",
|
|
},
|
|
"description": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "A textual description of the job.",
|
|
},
|
|
"environment": schema.MapAttribute{
|
|
ElementType: types.StringType,
|
|
Computed: true,
|
|
MarkdownDescription: "A set of environment variables mapping names to values to be defined during job execution.",
|
|
},
|
|
"identities": schema.SetAttribute{
|
|
Computed: true,
|
|
ElementType: types.StringType,
|
|
MarkdownDescription: "Set of eventline identities names to inject during job execution.",
|
|
},
|
|
"name": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of the job.",
|
|
},
|
|
"parameters": schema.ListNestedAttribute{
|
|
Computed: true,
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: map[string]schema.Attribute{
|
|
"description": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "A textual description of the parameter.",
|
|
},
|
|
"environment": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of an environment variable to be used to inject the value of this parameter during execution.",
|
|
},
|
|
"name": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of the parameter.",
|
|
},
|
|
"type": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The type of the parameter. The following types are supported:\n - number: Either an integer or an IEEE 754 double precision floating point value.\n - integer: An integer.\n - string: A character string.\n - boolean: A boolean.",
|
|
},
|
|
"values": schema.ListAttribute{
|
|
Computed: true,
|
|
ElementType: types.StringType,
|
|
MarkdownDescription: "For parameters of type string, the list of valid values.",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"retention": schema.Int64Attribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The number of days after which past executions of this job will be deleted. This value override the global job_retention setting.",
|
|
},
|
|
"runner": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"name": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of the runner.",
|
|
},
|
|
"identity": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of an identity to use for runners which require authentication. For example the ssh runner needs an identity to initiate an ssh connection.",
|
|
},
|
|
},
|
|
Computed: true,
|
|
MarkdownDescription: "The specification of the runner used to execute the job.",
|
|
},
|
|
"trigger": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"event": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The event to react to formatted as <connector>/<event>.",
|
|
},
|
|
"identity": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of an identity to use for events which require authentication. For example the github/push event needs an identity to create the GitHub hook used to listen to push events.",
|
|
},
|
|
},
|
|
Computed: true,
|
|
MarkdownDescription: "The specification of a trigger indicating when to execute the job.",
|
|
},
|
|
"steps": schema.ListNestedAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "A list of steps which will be executed sequentially.",
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: map[string]schema.Attribute{
|
|
"code": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The fragment of code to execute for this step.",
|
|
},
|
|
"command": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"arguments": schema.ListAttribute{
|
|
Computed: true,
|
|
ElementType: types.StringType,
|
|
MarkdownDescription: "The list of arguments to pass to the command.",
|
|
},
|
|
"name": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The name of the command.",
|
|
},
|
|
},
|
|
Computed: true,
|
|
MarkdownDescription: "The command to execute for this step.",
|
|
},
|
|
"label": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "A short description of the step which will be displayed on the web interface.",
|
|
},
|
|
"script": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"arguments": schema.ListAttribute{
|
|
Computed: true,
|
|
ElementType: types.StringType,
|
|
MarkdownDescription: "The list of arguments to pass to the command.",
|
|
},
|
|
"content": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The script file contents.",
|
|
},
|
|
"path": schema.StringAttribute{
|
|
Computed: true,
|
|
MarkdownDescription: "The path of the script file relative to the job file.",
|
|
},
|
|
},
|
|
Computed: true,
|
|
MarkdownDescription: "The command to execute for this step.",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Computed: true,
|
|
MarkdownDescription: "The specification of the job.",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"project_id": schema.StringAttribute{
|
|
MarkdownDescription: "The identifier of the project the jobs are part of.",
|
|
Required: true,
|
|
},
|
|
},
|
|
MarkdownDescription: "Use this data source to retrieve information about existing eventline jobs.",
|
|
}
|
|
}
|
|
|
|
func (d *JobsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
|
d.client, _ = req.ProviderData.(*evcli.Client)
|
|
}
|
|
|
|
func (d *JobsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
|
var data JobsDataSourceModel
|
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
var id ksuid.KSUID
|
|
if err := id.Parse(data.ProjectId.ValueString()); err != nil {
|
|
resp.Diagnostics.AddError("KsuidParse", fmt.Sprintf("Unable to parse project id, got error: %s", err))
|
|
return
|
|
}
|
|
d.client.ProjectId = &id
|
|
jobs, err := d.client.FetchJobs()
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("FetchJobs", fmt.Sprintf("Unable to fetch jobs, got error: %s", err))
|
|
return
|
|
}
|
|
jobList := make([]JobDataSourceModel, len(jobs))
|
|
for i, job := range jobs {
|
|
environment, _ := types.MapValueFrom(ctx, types.StringType, job.Spec.Environment)
|
|
identities, _ := types.SetValueFrom(ctx, types.StringType, job.Spec.Identities)
|
|
jobList[i] = JobDataSourceModel{
|
|
Disabled: types.BoolValue(job.Disabled),
|
|
Id: types.StringValue(job.Id.String()),
|
|
Spec: JobSpecDataSourceModel{
|
|
Concurrent: types.BoolValue(job.Spec.Concurrent),
|
|
Description: types.StringValue(job.Spec.Description),
|
|
Environment: environment,
|
|
Identities: identities,
|
|
Name: types.StringValue(job.Spec.Name),
|
|
Retention: types.Int64Value(int64(job.Spec.Retention)),
|
|
},
|
|
}
|
|
jobParameters := make([]ParameterDataSourceModel, len(job.Spec.Parameters))
|
|
for j, parameter := range job.Spec.Parameters {
|
|
values, _ := types.ListValueFrom(ctx, types.StringType, parameter.Values)
|
|
jobParameters[j] = ParameterDataSourceModel{
|
|
Description: types.StringValue(parameter.Description),
|
|
Environment: types.StringValue(parameter.Environment),
|
|
Name: types.StringValue(parameter.Name),
|
|
Type: types.StringValue(string(parameter.Type)),
|
|
Values: values,
|
|
}
|
|
}
|
|
jobList[i].Spec.Parameters = jobParameters
|
|
if job.Spec.Runner != nil {
|
|
jobList[i].Spec.Runner = &RunnerDataSourceModel{
|
|
Name: types.StringValue(job.Spec.Runner.Name),
|
|
Identity: types.StringValue(job.Spec.Runner.Identity),
|
|
}
|
|
}
|
|
jobSteps := make([]StepDataSourceModel, len(job.Spec.Steps))
|
|
for j, step := range job.Spec.Steps {
|
|
jobSteps[j] = StepDataSourceModel{
|
|
Code: types.StringValue(step.Code),
|
|
Label: types.StringValue(step.Label),
|
|
}
|
|
if step.Command != nil {
|
|
arguments, _ := types.ListValueFrom(ctx, types.StringType, step.Command.Arguments)
|
|
jobSteps[j].Command = &StepCommandDataSourceModel{
|
|
Arguments: arguments,
|
|
Name: types.StringValue(step.Command.Name),
|
|
}
|
|
}
|
|
if step.Script != nil {
|
|
arguments, _ := types.ListValueFrom(ctx, types.StringType, step.Script.Arguments)
|
|
jobSteps[j].Script = &StepScriptDataSourceModel{
|
|
Arguments: arguments,
|
|
Content: types.StringValue(step.Script.Content),
|
|
Path: types.StringValue(step.Script.Path),
|
|
}
|
|
}
|
|
}
|
|
jobList[i].Spec.Steps = jobSteps
|
|
if job.Spec.Trigger != nil {
|
|
jobList[i].Spec.Trigger = &TriggerDataSourceModel{
|
|
Event: types.StringValue(job.Spec.Trigger.Event.String()),
|
|
Identity: types.StringValue(job.Spec.Trigger.Identity),
|
|
}
|
|
}
|
|
}
|
|
data.Elements = jobList
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
}
|