diff --git a/code_generator/provider_code_spec.json b/code_generator/provider_code_spec.json index 7ec6b77..3eec48e 100644 --- a/code_generator/provider_code_spec.json +++ b/code_generator/provider_code_spec.json @@ -365,6 +365,41 @@ ] } }, + { + "name": "organization_robot", + "schema": { + "attributes": [ + { + "name": "description", + "string": { + "computed_optional_required": "computed", + "description": "Text description" + } + }, + { + "name": "fullname", + "string": { + "computed_optional_required": "computed", + "description": "Robot full name" + } + }, + { + "name": "name", + "string": { + "computed_optional_required": "required", + "description": "Robot short name" + } + }, + { + "name": "orgname", + "string": { + "computed_optional_required": "required", + "description": "Organization name" + } + } + ] + } + }, { "name": "organization_team", "schema": { diff --git a/internal/datasource_organization_robot/organization_robot_data_source_gen.go b/internal/datasource_organization_robot/organization_robot_data_source_gen.go new file mode 100644 index 0000000..6b8a941 --- /dev/null +++ b/internal/datasource_organization_robot/organization_robot_data_source_gen.go @@ -0,0 +1,44 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package datasource_organization_robot + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func OrganizationRobotDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Description: "Text description", + MarkdownDescription: "Text description", + }, + "fullname": schema.StringAttribute{ + Computed: true, + Description: "Robot full name", + MarkdownDescription: "Robot full name", + }, + "name": schema.StringAttribute{ + Required: true, + Description: "Robot short name", + MarkdownDescription: "Robot short name", + }, + "orgname": schema.StringAttribute{ + Required: true, + Description: "Organization name", + MarkdownDescription: "Organization name", + }, + }, + } +} + +type OrganizationRobotModel struct { + Description types.String `tfsdk:"description"` + Fullname types.String `tfsdk:"fullname"` + Name types.String `tfsdk:"name"` + Orgname types.String `tfsdk:"orgname"` +} diff --git a/internal/provider/organization_robot_data_source.go b/internal/provider/organization_robot_data_source.go new file mode 100644 index 0000000..7e41b3e --- /dev/null +++ b/internal/provider/organization_robot_data_source.go @@ -0,0 +1,100 @@ +package provider + +import ( + "context" + "encoding/json" + "fmt" + "io" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/enthought/terraform-provider-quay/quay_api" + "terraform-provider-quay/internal/datasource_organization_robot" +) + +var ( + _ datasource.DataSource = (*organizationRobotDataSource)(nil) + _ datasource.DataSourceWithConfigure = (*organizationRobotDataSource)(nil) +) + +func NewOrganizationRobotDataSource() datasource.DataSource { + return &organizationRobotDataSource{} +} + +type organizationRobotDataSource struct { + client *quay_api.APIClient +} + +func (d *organizationRobotDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_organization_robot" +} + +func (d *organizationRobotDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = datasource_organization_robot.OrganizationRobotDataSourceSchema(ctx) +} + +func (d *organizationRobotDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data datasource_organization_robot.OrganizationRobotModel + var resRobotData organizationRobotModelJSON + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Create variables + orgName := data.Orgname.ValueString() + robotName := data.Name.ValueString() + + // Get robot + httpRes, err := d.client.RobotAPI.GetOrgRobot(context.Background(), orgName, robotName).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError( + "Error reading Quay org robot", + "Could not read Quay org robot, unexpected error: "+errDetail) + return + } + body, err := io.ReadAll(httpRes.Body) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay team", + "Could not read Quay team, unexpected error: "+err.Error()) + return + } + err = json.Unmarshal(body, &resRobotData) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay team", + "Could not read Quay team, unexpected error: "+err.Error()) + return + } + + // Set Description + data.Description = types.StringValue(resRobotData.Description) + + // Set robot full name + data.Fullname = types.StringValue(orgName + "+" + robotName) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (d *organizationRobotDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*quay_api.APIClient) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *quay_api.APIClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + + d.client = client +} diff --git a/internal/provider/organization_robot_data_source_test.go b/internal/provider/organization_robot_data_source_test.go new file mode 100644 index 0000000..bef1fb5 --- /dev/null +++ b/internal/provider/organization_robot_data_source_test.go @@ -0,0 +1,44 @@ +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccOrganizationRobotDataSource(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: providerConfig + ` +resource "quay_organization" "org_robot_data" { + name = "org_robot_data" + email = "quay+org_robot_data@example.com" +} + +resource "quay_organization_robot" "test" { + name = "test" + orgname = quay_organization.org_robot_data.name + description = "test" +} + +data "quay_organization_robot" "test" { + name = "test" + orgname = quay_organization.org_robot_data.name + + depends_on = [ + quay_organization_robot.test + ] +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("quay_organization_robot.test", "name", "test"), + resource.TestCheckResourceAttr("quay_organization_robot.test", "orgname", "org_robot_data"), + resource.TestCheckResourceAttr("quay_organization_robot.test", "description", "test"), + resource.TestCheckResourceAttr("quay_organization_robot.test", "fullname", "org_robot_data+test"), + ), + }, + }, + }) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index fd3a35c..7b025ae 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -154,6 +154,7 @@ func (p *quayProvider) DataSources(_ context.Context) []func() datasource.DataSo NewRepositoryDataSource, NewOrganizationTeamPermissionDataSource, NewOrganizationTeamDataSource, + NewOrganizationRobotDataSource, } }