Skip to content

Commit

Permalink
feat: add support for optionally hard deleting schemas (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
dstrates authored Aug 13, 2024
1 parent 7da6415 commit 29d9136
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ resource "schemaregistry_schema" "example" {
subject = "example"
schema_type = "AVRO"
compatibility_level = "NONE"
hard_delete = false
schema = file("path/to/your/schema.avsc")
# optional list of schema references
Expand Down
4 changes: 3 additions & 1 deletion docs/resources/schemaregistry_schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ resource "schemaregistry_schema" "example" {
subject = "example"
schema_type = "AVRO"
compatibility_level = "FORWARD_TRANSITIVE"
hard_delete = true
schema = "example"
# optional list of schema references
Expand All @@ -37,8 +38,9 @@ The following arguments are supported:
* `subject` - (Required) The subject related to the schema.
* `schema_type` - (Required) The schema type.
* `compatibility_level` - (Required) The schema compatibility level.
* `schema` - (Required) The schema string.
* `schema` - (Optional) The schema string.
* `references` - (Optional) The referenced schema list.
* `hard_delete` - (Optional) Controls whether the subject is soft or hard deleted.

## Attributes Reference

Expand Down
1 change: 1 addition & 0 deletions examples/resources/schemaregistry_schema/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ resource "schemaregistry_schema" "example" {
schema = "{\"type\":\"record\",\"name\":\"Test\",\"fields\":[{\"name\":\"f1\",\"type\":\"string\"}]}"
schema_type = "AVRO"
compatibility_level = "FORWARD_TRANSITIVE"
hard_delete = true
}
17 changes: 12 additions & 5 deletions internal/provider/data_source_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ type schemaDataSourceModel struct {
Version types.Int64 `tfsdk:"version"`
Reference types.List `tfsdk:"reference"`
CompatibilityLevel types.String `tfsdk:"compatibility_level"`
HardDelete types.Bool `tfsdk:"hard_delete"`
}

// Metadata returns the data source type name.
func (d *schemaDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
func (d *schemaDataSource) Metadata(_ context.Context, req datasource.MetadataRequest,
resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_schema"
}

Expand All @@ -55,15 +57,15 @@ func (d *schemaDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
Description: "Fetches a schema from the Schema Registry.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "UID for the schema, which is the subject name.",
Description: "The globally unique ID of the schema.",
Computed: true,
},
"subject": schema.StringAttribute{
Description: "The subject related to the schema.",
Required: true,
},
"schema": schema.StringAttribute{
Description: "The schema string.",
Description: "The schema definition.",
Computed: true,
CustomType: jsontypes.NormalizedType{},
},
Expand Down Expand Up @@ -107,7 +109,7 @@ func (d *schemaDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
},
},
"compatibility_level": schema.StringAttribute{
Description: "The compatibility level of the schema. Default is FORWARD_TRANSITIVE.",
Description: "The compatibility level of the schema.",
Computed: true,
Validators: []validator.String{
stringvalidator.OneOf(
Expand All @@ -121,12 +123,17 @@ func (d *schemaDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
),
},
},
"hard_delete": schema.BoolAttribute{
Description: "Controls whether a schema should be soft or hard deleted.",
Optional: true,
},
},
}
}

// Configure adds the provider configured client to the data source.
func (d *schemaDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
func (d *schemaDataSource) Configure(_ context.Context, req datasource.ConfigureRequest,
resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/data_source_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ resource "schemaregistry_schema" "test_01" {
subject = "%s"
schema_type = "AVRO"
compatibility_level = "NONE"
hard_delete = false
schema = jsonencode({
"type": "record",
"name": "Test",
Expand Down Expand Up @@ -124,6 +125,7 @@ resource "schemaregistry_schema" "test_01" {
subject = "%s"
schema_type = "AVRO"
compatibility_level = "BACKWARD"
hard_delete = false
schema = jsonencode({
type = "record",
name = "TestUpdated",
Expand Down
22 changes: 18 additions & 4 deletions internal/provider/resource_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
Expand Down Expand Up @@ -43,6 +44,7 @@ type schemaResourceModel struct {
Version types.Int64 `tfsdk:"version"`
Reference types.List `tfsdk:"references"`
CompatibilityLevel types.String `tfsdk:"compatibility_level"`
HardDelete types.Bool `tfsdk:"hard_delete"`
}

// Metadata returns the resource type name.
Expand Down Expand Up @@ -73,7 +75,7 @@ func (r *schemaResource) Schema(_ context.Context, _ resource.SchemaRequest, res
},
"schema": schema.StringAttribute{
Description: "The schema definition.",
Required: true,
Optional: true,
CustomType: jsontypes.NormalizedType{},
Validators: []validator.String{
stringvalidator.LengthAtLeast(2),
Expand All @@ -85,7 +87,7 @@ func (r *schemaResource) Schema(_ context.Context, _ resource.SchemaRequest, res
},
"schema_type": schema.StringAttribute{
Description: "The schema format.",
Optional: true,
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
Expand Down Expand Up @@ -130,6 +132,7 @@ func (r *schemaResource) Schema(_ context.Context, _ resource.SchemaRequest, res
"compatibility_level": schema.StringAttribute{
Description: "The compatibility level of the schema.",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.OneOf(
"NONE",
Expand All @@ -142,6 +145,12 @@ func (r *schemaResource) Schema(_ context.Context, _ resource.SchemaRequest, res
),
},
},
"hard_delete": schema.BoolAttribute{
Description: "Controls whether a schema should be soft or hard deleted.",
Optional: true,
Computed: true,
Default: booldefault.StaticBool(false),
},
},
}
}
Expand Down Expand Up @@ -229,6 +238,7 @@ func (r *schemaResource) Create(ctx context.Context, req resource.CreateRequest,
plan.SchemaType = types.StringValue(schemaTypeStr)
plan.Version = types.Int64Value(1) // Set the version to 1 for new schema
plan.Reference = FromRegistryReferences(schema.References())
plan.HardDelete = types.BoolValue(plan.HardDelete.ValueBool())

// Set state to fully populated data
diags = resp.State.Set(ctx, plan)
Expand Down Expand Up @@ -276,6 +286,7 @@ func (r *schemaResource) Read(ctx context.Context, req resource.ReadRequest, res
state.SchemaType = types.StringValue(schemaType)
state.Version = types.Int64Value(int64(schema.Version()))
state.Reference = FromRegistryReferences(schema.References())
state.HardDelete = types.BoolValue(state.HardDelete.ValueBool())

// Set refreshed state
diags = resp.State.Set(ctx, &state)
Expand Down Expand Up @@ -336,6 +347,7 @@ func (r *schemaResource) Update(ctx context.Context, req resource.UpdateRequest,
plan.SchemaID = types.Int64Value(int64(schema.ID()))
plan.Version = types.Int64Value(int64(schema.Version()))
plan.Reference = FromRegistryReferences(schema.References())
plan.HardDelete = types.BoolValue(plan.HardDelete.ValueBool())

diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
Expand All @@ -354,8 +366,10 @@ func (r *schemaResource) Delete(ctx context.Context, req resource.DeleteRequest,
return
}

// Soft deletes existing schema
err := r.client.DeleteSubject(state.Subject.ValueString(), false)
deletionType := state.HardDelete.ValueBool()

// Delete existing schema
err := r.client.DeleteSubject(state.Subject.ValueString(), deletionType)
if err != nil {
resp.Diagnostics.AddError(
"Error Deleting Schema",
Expand Down
4 changes: 4 additions & 0 deletions internal/provider/resource_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestAccSchemaResource_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "schema", NormalizedJSON(initialSchema)),
resource.TestCheckResourceAttr(resourceName, "schema_type", "AVRO"),
resource.TestCheckResourceAttr(resourceName, "compatibility_level", "NONE"),
resource.TestCheckResourceAttr(resourceName, "hard_delete", "false"),
resource.TestCheckResourceAttrSet(resourceName, "schema_id"),
resource.TestCheckResourceAttrSet(resourceName, "version"),
),
Expand All @@ -73,6 +74,7 @@ func TestAccSchemaResource_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "schema", NormalizedJSON(updatedSchema)),
resource.TestCheckResourceAttr(resourceName, "schema_type", "AVRO"),
resource.TestCheckResourceAttr(resourceName, "compatibility_level", "BACKWARD"),
resource.TestCheckResourceAttr(resourceName, "hard_delete", "true"),
resource.TestCheckResourceAttrSet(resourceName, "schema_id"),
resource.TestCheckResourceAttrSet(resourceName, "version"),
),
Expand Down Expand Up @@ -158,6 +160,7 @@ resource "schemaregistry_schema" "test_01" {
subject = "%s"
schema_type = "AVRO"
compatibility_level = "NONE"
hard_delete = false
schema = jsonencode({
"type": "record",
"name": "Test",
Expand Down Expand Up @@ -203,6 +206,7 @@ resource "schemaregistry_schema" "test_01" {
subject = "%s"
schema_type = "AVRO"
compatibility_level = "BACKWARD"
hard_delete = true
schema = jsonencode({
"type": "record",
"name": "TestUpdated",
Expand Down

0 comments on commit 29d9136

Please sign in to comment.