Skip to content

Commit

Permalink
rework: improve quality profile write method
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuochi committed Jun 21, 2023
1 parent 78a628f commit 32c87b8
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 56 deletions.
19 changes: 19 additions & 0 deletions internal/provider/quality_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/devopsarr/radarr-go/radarr"
"github.com/devopsarr/terraform-provider-radarr/internal/helpers"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -26,6 +27,24 @@ type QualityDataSource struct {
client *radarr.APIClient
}

// Quality is part of QualityGroup.
type Quality struct {
Name types.String `tfsdk:"name"`
Source types.String `tfsdk:"source"`
ID types.Int64 `tfsdk:"id"`
Resolution types.Int64 `tfsdk:"resolution"`
}

func (q Quality) getType() attr.Type {
return types.ObjectType{}.WithAttributeTypes(
map[string]attr.Type{
"name": types.StringType,
"source": types.StringType,
"id": types.Int64Type,
"resolution": types.Int64Type,
})
}

func (d *QualityDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_" + qualityDataSourceName
}
Expand Down
103 changes: 69 additions & 34 deletions internal/provider/quality_profile_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (

"github.com/devopsarr/radarr-go/radarr"
"github.com/devopsarr/terraform-provider-radarr/internal/helpers"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

Expand Down Expand Up @@ -48,19 +49,35 @@ type QualityProfile struct {
UpgradeAllowed types.Bool `tfsdk:"upgrade_allowed"`
}

func (p QualityProfile) getType() attr.Type {
return types.ObjectType{}.WithAttributeTypes(
map[string]attr.Type{
"quality_groups": types.SetType{}.WithElementType(QualityGroup{}.getType()),
"format_items": types.SetType{}.WithElementType(FormatItem{}.getType()),
"language": QualityLanguage{}.getType(),
"name": types.StringType,
"id": types.Int64Type,
"cutoff": types.Int64Type,
"min_format_score": types.Int64Type,
"cutoff_format_score": types.Int64Type,
"upgrade_allowed": types.BoolType,
})
}

// QualityGroup is part of QualityProfile.
type QualityGroup struct {
Qualities types.Set `tfsdk:"qualities"`
Name types.String `tfsdk:"name"`
ID types.Int64 `tfsdk:"id"`
}

// Quality is part of QualityGroup.
type Quality struct {
Name types.String `tfsdk:"name"`
Source types.String `tfsdk:"source"`
ID types.Int64 `tfsdk:"id"`
Resolution types.Int64 `tfsdk:"resolution"`
func (q QualityGroup) getType() attr.Type {
return types.ObjectType{}.WithAttributeTypes(
map[string]attr.Type{
"qualities": types.SetType{}.WithElementType(Quality{}.getType()),
"name": types.StringType,
"id": types.Int64Type,
})
}

// FormatItem is part of QualityProfile.
Expand All @@ -70,12 +87,29 @@ type FormatItem struct {
Score types.Int64 `tfsdk:"score"`
}

func (f FormatItem) getType() attr.Type {
return types.ObjectType{}.WithAttributeTypes(
map[string]attr.Type{
"name": types.StringType,
"format": types.Int64Type,
"score": types.Int64Type,
})
}

// QualityLanguage is part of QualityProfile.
type QualityLanguage struct {
Name types.String `tfsdk:"name"`
ID types.Int64 `tfsdk:"id"`
}

func (q QualityLanguage) getType() attr.Type {
return types.ObjectType{}.WithAttributeTypes(
map[string]attr.Type{
"name": types.StringType,
"id": types.Int64Type,
})
}

func (r *QualityProfileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_" + qualityProfileResourceName
}
Expand Down Expand Up @@ -352,18 +386,18 @@ func (r *QualityProfileResource) ImportState(ctx context.Context, req resource.I
}

func (p *QualityProfile) write(ctx context.Context, profile *radarr.QualityProfileResource, diags *diag.Diagnostics) {
var tempDiag diag.Diagnostics

p.UpgradeAllowed = types.BoolValue(profile.GetUpgradeAllowed())
p.ID = types.Int64Value(int64(profile.GetId()))
p.Name = types.StringValue(profile.GetName())
p.Cutoff = types.Int64Value(int64(profile.GetCutoff()))
p.CutoffFormatScore = types.Int64Value(int64(profile.GetCutoffFormatScore()))
p.MinFormatScore = types.Int64Value(int64(profile.GetMinFormatScore()))
p.QualityGroups = types.SetValueMust(QualityProfileResource{}.getQualityGroupSchema().Type(), nil)
p.FormatItems = types.SetValueMust(QualityProfileResource{}.getFormatItemsSchema().Type(), nil)

qualityGroups := make([]QualityGroup, len(profile.GetItems()))
for n, g := range profile.GetItems() {
qualityGroups[n].write(ctx, g)
qualityGroups[n].write(ctx, g, diags)
}

formatItems := make([]FormatItem, len(profile.GetFormatItems()))
Expand All @@ -373,40 +407,41 @@ func (p *QualityProfile) write(ctx context.Context, profile *radarr.QualityProfi

language := QualityLanguage{}
language.write(profile.Language)
tfsdk.ValueFrom(ctx, language, QualityProfileResource{}.getQualityLanguageSchema().Type(), &p.Language)

tfsdk.ValueFrom(ctx, qualityGroups, p.QualityGroups.Type(ctx), &p.QualityGroups)
tfsdk.ValueFrom(ctx, formatItems, p.FormatItems.Type(ctx), &p.FormatItems)
p.Language, tempDiag = types.ObjectValueFrom(ctx, language.getType().(attr.TypeWithAttributeTypes).AttributeTypes(), language)
diags.Append(tempDiag...)
p.QualityGroups, tempDiag = types.SetValueFrom(ctx, QualityGroup{}.getType(), qualityGroups)
diags.Append(tempDiag...)
p.FormatItems, tempDiag = types.SetValueFrom(ctx, FormatItem{}.getType(), formatItems)
diags.Append(tempDiag...)
}

func (q *QualityGroup) write(ctx context.Context, group *radarr.QualityProfileQualityItemResource) {
var (
name string
id int64
qualities []Quality
)
func (q *QualityGroup) write(ctx context.Context, group *radarr.QualityProfileQualityItemResource, diags *diag.Diagnostics) {
var tempDiag diag.Diagnostics

name := types.StringValue(group.GetName())
id := types.Int64Value(int64(group.GetId()))

qualities := make([]Quality, len(group.GetItems()))
for m, q := range group.GetItems() {
qualities[m].write(q)
}

if len(group.GetItems()) == 0 {
name = types.StringNull()
id = types.Int64Null()
qualities = []Quality{{
ID: types.Int64Value(int64(group.Quality.GetId())),
Name: types.StringValue(group.Quality.GetName()),
Source: types.StringValue(string(group.Quality.GetSource())),
Resolution: types.Int64Value(int64(group.Quality.GetResolution())),
}}
} else {
name = group.GetName()
id = int64(group.GetId())
qualities = make([]Quality, len(group.GetItems()))
for m, q := range group.GetItems() {
qualities[m].write(q)
}
}

q.Name = types.StringValue(name)
q.ID = types.Int64Value(id)
q.Qualities = types.SetValueMust(QualityProfileResource{}.getQualitySchema().Type(), nil)

tfsdk.ValueFrom(ctx, qualities, q.Qualities.Type(ctx), &q.Qualities)
q.Name = name
q.ID = id
q.Qualities, tempDiag = types.SetValueFrom(ctx, Quality{}.getType(), &qualities)
diags.Append(tempDiag...)
}

func (q *Quality) write(quality *radarr.QualityProfileQualityItemResource) {
Expand All @@ -430,8 +465,8 @@ func (l *QualityLanguage) write(language *radarr.Language) {
func (p *QualityProfile) read(ctx context.Context, diags *diag.Diagnostics) *radarr.QualityProfileResource {
groups := make([]QualityGroup, len(p.QualityGroups.Elements()))
diags.Append(p.QualityGroups.ElementsAs(ctx, &groups, false)...)
qualities := make([]*radarr.QualityProfileQualityItemResource, len(groups))

qualities := make([]*radarr.QualityProfileQualityItemResource, len(groups))
for n, g := range groups {
q := make([]Quality, len(g.Qualities.Elements()))
diags.Append(g.Qualities.ElementsAs(ctx, &q, false)...)
Expand Down Expand Up @@ -467,14 +502,14 @@ func (p *QualityProfile) read(ctx context.Context, diags *diag.Diagnostics) *rad

formats := make([]FormatItem, len(p.FormatItems.Elements()))
diags.Append(p.FormatItems.ElementsAs(ctx, &formats, true)...)
formatItems := make([]*radarr.ProfileFormatItemResource, len(formats))

formatItems := make([]*radarr.ProfileFormatItemResource, len(formats))
for n, f := range formats {
formatItems[n] = f.read()
}

language := QualityLanguage{}
tfsdk.ValueAs(ctx, p.Language, &language)
p.Language.As(ctx, &language, basetypes.ObjectAsOptions{})

profile := radarr.NewQualityProfileResource()
profile.SetUpgradeAllowed(p.UpgradeAllowed.ValueBool())
Expand Down
28 changes: 6 additions & 22 deletions internal/provider/quality_profiles_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"github.com/devopsarr/terraform-provider-radarr/internal/helpers"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
)
Expand Down Expand Up @@ -164,13 +162,6 @@ func (d *QualityProfilesDataSource) Configure(ctx context.Context, req datasourc
}

func (d *QualityProfilesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data *QualityProfiles

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}
// Get qualityprofiles current value
response, _, err := d.client.QualityProfileApi.ListQualityProfile(ctx).Execute()
if err != nil {
Expand All @@ -181,19 +172,12 @@ func (d *QualityProfilesDataSource) Read(ctx context.Context, req datasource.Rea

tflog.Trace(ctx, "read "+qualityProfilesDataSourceName)
// Map response body to resource schema attribute
profiles := *writeQualitiyprofiles(ctx, response)
tfsdk.ValueFrom(ctx, profiles, data.QualityProfiles.Type(ctx), &data.QualityProfiles)

// TODO: remove ID once framework support tests without ID https://www.terraform.io/plugin/framework/acctests#implement-id-attribute
data.ID = types.StringValue(strconv.Itoa(len(response)))
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func writeQualitiyprofiles(ctx context.Context, qualities []*radarr.QualityProfileResource) *[]QualityProfile {
output := make([]QualityProfile, len(qualities))
for i, p := range qualities {
output[i].write(ctx, p, &diag.Diagnostics{})
profiles := make([]QualityProfile, len(response))
for i, p := range response {
profiles[i].write(ctx, p, &resp.Diagnostics)
}

return &output
profileList, diags := types.SetValueFrom(ctx, QualityProfile{}.getType(), profiles)
resp.Diagnostics.Append(diags...)
resp.Diagnostics.Append(resp.State.Set(ctx, QualityProfiles{QualityProfiles: profileList, ID: types.StringValue(strconv.Itoa(len(response)))})...)
}

0 comments on commit 32c87b8

Please sign in to comment.