diff --git a/docs/data-sources/repository_registry.md b/docs/data-sources/repository_registry.md new file mode 100644 index 0000000..029da17 --- /dev/null +++ b/docs/data-sources/repository_registry.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "woodpecker_repository_registry Data Source - terraform-provider-woodpecker" +subcategory: "" +description: |- + Use this data source to retrieve information about a container registry in a specific repository. +--- + +# woodpecker_repository_registry (Data Source) + +Use this data source to retrieve information about a container registry in a specific repository. + +## Example Usage + +```terraform +resource "woodpecker_repository" "test_repo" { + full_name = "Kichiyaki/test-repo" +} + +data "woodpecker_repository_secret" "test_secret" { + repository_id = woodpecker_repository.test_repo.id + address = "docker.io" +} +``` + + +## Schema + +### Required + +- `address` (String) the address of the registry (e.g. docker.io) +- `repository_id` (Number) the ID of the repository + +### Read-Only + +- `email` (String) email used for authentication +- `id` (Number) the id of the registry +- `username` (String) username used for authentication diff --git a/examples/data-sources/woodpecker_repository_registry/data-source.tf b/examples/data-sources/woodpecker_repository_registry/data-source.tf new file mode 100644 index 0000000..bd05c60 --- /dev/null +++ b/examples/data-sources/woodpecker_repository_registry/data-source.tf @@ -0,0 +1,8 @@ +resource "woodpecker_repository" "test_repo" { + full_name = "Kichiyaki/test-repo" +} + +data "woodpecker_repository_secret" "test_secret" { + repository_id = woodpecker_repository.test_repo.id + address = "docker.io" +} diff --git a/internal/data_source_repository_registry.go b/internal/data_source_repository_registry.go new file mode 100644 index 0000000..6ed83a8 --- /dev/null +++ b/internal/data_source_repository_registry.go @@ -0,0 +1,93 @@ +package internal + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/woodpecker-ci/woodpecker/woodpecker-go/woodpecker" +) + +type repositoryRegistryDataSource struct { + client woodpecker.Client +} + +var _ datasource.DataSource = (*repositoryRegistryDataSource)(nil) +var _ datasource.DataSourceWithConfigure = (*repositoryRegistryDataSource)(nil) + +func newRepositoryRegistryDataSource() datasource.DataSource { + return &repositoryRegistryDataSource{} +} + +func (d *repositoryRegistryDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_repository_registry" +} + +func (d *repositoryRegistryDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "Use this data source to retrieve information about a container registry in a specific repository.", + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + Description: "the id of the registry", + }, + "repository_id": schema.Int64Attribute{ + Required: true, + Description: "the ID of the repository", + }, + "address": schema.StringAttribute{ + Required: true, + Description: "the address of the registry (e.g. docker.io)", + }, + "username": schema.StringAttribute{ + Computed: true, + Description: "username used for authentication", + }, + "email": schema.StringAttribute{ + Computed: true, + Description: "email used for authentication", + }, + }, + } +} + +func (d *repositoryRegistryDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(woodpecker.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected woodpecker.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.client = client +} + +func (d *repositoryRegistryDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data repositoryRegistryDataSourceModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + registry, err := d.client.Registry(data.RepositoryID.ValueInt64(), data.Address.ValueString()) + if err != nil { + resp.Diagnostics.AddError("Couldn't get registry data", err.Error()) + return + } + + resp.Diagnostics.Append(data.setValues(ctx, registry)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/internal/data_source_repository_registry_test.go b/internal/data_source_repository_registry_test.go new file mode 100644 index 0000000..133c1d8 --- /dev/null +++ b/internal/data_source_repository_registry_test.go @@ -0,0 +1,48 @@ +package internal_test + +import ( + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestRepositoryRegistryDataSource(t *testing.T) { + t.Parallel() + + repo := createRepo(t) + address := uuid.NewString() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` +resource "woodpecker_repository" "test_repo" { + full_name = "%s" +} + +resource "woodpecker_repository_registry" "test_registry" { + repository_id = woodpecker_repository.test_repo.id + address = "%s" + username = "test" + password = "test" +} + +data "woodpecker_repository_registry" "test_registry" { + repository_id = woodpecker_repository_registry.test_registry.repository_id + address = woodpecker_repository_registry.test_registry.address +} +`, repo.FullName, address), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.woodpecker_repository_registry.test_registry", "id"), + resource.TestCheckResourceAttrSet("data.woodpecker_repository_registry.test_registry", "repository_id"), + resource.TestCheckResourceAttr("data.woodpecker_repository_registry.test_registry", "address", address), + resource.TestCheckResourceAttr("data.woodpecker_repository_registry.test_registry", "username", "test"), + ), + }, + }, + }) +} diff --git a/internal/models.go b/internal/models.go index 527ecf4..c459882 100644 --- a/internal/models.go +++ b/internal/models.go @@ -251,7 +251,7 @@ func (m *repositoryCronModel) toWoodpeckerModel(_ context.Context) (*woodpecker. }, nil } -type repositoryRegistryModel struct { +type repositoryRegistryResourceModel struct { ID types.Int64 `tfsdk:"id"` RepositoryID types.Int64 `tfsdk:"repository_id"` Address types.String `tfsdk:"address"` @@ -260,7 +260,7 @@ type repositoryRegistryModel struct { Email types.String `tfsdk:"email"` } -func (m *repositoryRegistryModel) setValues(_ context.Context, registry *woodpecker.Registry) diag.Diagnostics { +func (m *repositoryRegistryResourceModel) setValues(_ context.Context, registry *woodpecker.Registry) diag.Diagnostics { m.ID = types.Int64Value(registry.ID) m.Address = types.StringValue(registry.Address) m.Username = types.StringValue(registry.Username) @@ -268,7 +268,7 @@ func (m *repositoryRegistryModel) setValues(_ context.Context, registry *woodpec return nil } -func (m *repositoryRegistryModel) toWoodpeckerModel(_ context.Context) (*woodpecker.Registry, diag.Diagnostics) { +func (m *repositoryRegistryResourceModel) toWoodpeckerModel(_ context.Context) (*woodpecker.Registry, diag.Diagnostics) { return &woodpecker.Registry{ ID: m.ID.ValueInt64(), Address: m.Address.ValueString(), @@ -277,3 +277,19 @@ func (m *repositoryRegistryModel) toWoodpeckerModel(_ context.Context) (*woodpec Email: m.Email.ValueString(), }, nil } + +type repositoryRegistryDataSourceModel struct { + ID types.Int64 `tfsdk:"id"` + RepositoryID types.Int64 `tfsdk:"repository_id"` + Address types.String `tfsdk:"address"` + Username types.String `tfsdk:"username"` + Email types.String `tfsdk:"email"` +} + +func (m *repositoryRegistryDataSourceModel) setValues(_ context.Context, registry *woodpecker.Registry) diag.Diagnostics { + m.ID = types.Int64Value(registry.ID) + m.Address = types.StringValue(registry.Address) + m.Username = types.StringValue(registry.Username) + m.Email = types.StringValue(registry.Email) + return nil +} diff --git a/internal/provider.go b/internal/provider.go index e88e679..43844d1 100644 --- a/internal/provider.go +++ b/internal/provider.go @@ -61,6 +61,7 @@ func (p *woodpeckerProvider) DataSources(_ context.Context) []func() datasource. newRepositoryDataSource, newRepositorySecretDataSource, newRepositoryCronDataSource, + newRepositoryRegistryDataSource, } } diff --git a/internal/resource_repository_registry.go b/internal/resource_repository_registry.go index 5cb37f3..5f03204 100644 --- a/internal/resource_repository_registry.go +++ b/internal/resource_repository_registry.go @@ -99,7 +99,7 @@ func (r *repositoryRegistryResource) Configure(_ context.Context, req resource.C } func (r *repositoryRegistryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data repositoryRegistryModel + var data repositoryRegistryResourceModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { @@ -134,7 +134,7 @@ func (r *repositoryRegistryResource) Create(ctx context.Context, req resource.Cr } func (r *repositoryRegistryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data repositoryRegistryModel + var data repositoryRegistryResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &data)...) if resp.Diagnostics.HasError() { @@ -155,7 +155,7 @@ func (r *repositoryRegistryResource) Read(ctx context.Context, req resource.Read } func (r *repositoryRegistryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data repositoryRegistryModel + var data repositoryRegistryResourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) if resp.Diagnostics.HasError() { @@ -183,7 +183,7 @@ func (r *repositoryRegistryResource) Update(ctx context.Context, req resource.Up } func (r *repositoryRegistryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data repositoryRegistryModel + var data repositoryRegistryResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &data)...) if resp.Diagnostics.HasError() {