Skip to content

Commit

Permalink
Merge pull request #158 from Juniper/feat/157
Browse files Browse the repository at this point in the history
Feat/157
  • Loading branch information
rajagopalans authored Jun 23, 2023
2 parents 7a8c1f5 + 7705a0a commit 220e145
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 23 deletions.
6 changes: 3 additions & 3 deletions apstra/data_source_property_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ func (o *dataSourcePropertySet) Read(ctx context.Context, req datasource.ReadReq
var ace apstra.ApstraClientErr

switch {
case !config.Label.IsNull():
api, err = o.client.GetPropertySetByLabel(ctx, config.Label.ValueString())
case !config.Name.IsNull():
api, err = o.client.GetPropertySetByLabel(ctx, config.Name.ValueString())
if err != nil && errors.As(err, &ace) && ace.Type() == apstra.ErrNotfound {
resp.Diagnostics.AddAttributeError(
path.Root("name"),
"PropertySet not found",
fmt.Sprintf("PropertySet with label %q not found", config.Label.ValueString()))
fmt.Sprintf("PropertySet with label %q not found", config.Name.ValueString()))
return
}
case !config.Id.IsNull():
Expand Down
30 changes: 24 additions & 6 deletions apstra/design/property_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import (
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
apstravalidator "terraform-provider-apstra/apstra/apstra_validator"
"terraform-provider-apstra/apstra/utils"
)

type PropertySet struct {
Id types.String `tfsdk:"id"`
Label types.String `tfsdk:"name"`
Values types.String `tfsdk:"data"`
Name types.String `tfsdk:"name"`
Data types.String `tfsdk:"data"`
Blueprints types.Set `tfsdk:"blueprints"`
Keys types.Set `tfsdk:"keys"`
}

func (o PropertySet) DataSourceAttributes() map[string]dataSourceSchema.Attribute {
Expand All @@ -42,6 +44,11 @@ func (o PropertySet) DataSourceAttributes() map[string]dataSourceSchema.Attribut
Computed: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"keys": dataSourceSchema.SetAttribute{
MarkdownDescription: "Set of keys defined in the Property Set.",
Computed: true,
ElementType: types.StringType,
},
"data": dataSourceSchema.StringAttribute{
MarkdownDescription: "A map of values in the Property Set in JSON format",
Computed: true,
Expand All @@ -68,6 +75,11 @@ func (o PropertySet) ResourceAttributes() map[string]resourceSchema.Attribute {
Required: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"keys": resourceSchema.SetAttribute{
MarkdownDescription: "Set of keys defined in the Property Set.",
Computed: true,
ElementType: types.StringType,
},
"data": resourceSchema.StringAttribute{
MarkdownDescription: "A map of values in the Property Set in JSON format",
Required: true,
Expand All @@ -82,16 +94,22 @@ func (o PropertySet) ResourceAttributes() map[string]resourceSchema.Attribute {
}

func (o *PropertySet) LoadApiData(ctx context.Context, in *apstra.PropertySetData, diags *diag.Diagnostics) {
o.Label = types.StringValue(in.Label)
o.Name = types.StringValue(in.Label)
var d diag.Diagnostics
o.Blueprints, d = types.SetValueFrom(ctx, types.StringType, in.Blueprints)
diags.Append(d...)
o.Values = types.StringValue(string(in.Values))
o.Data = types.StringValue(string(in.Values))
k, err := utils.GetKeysFromJSON(o.Data)
if err != nil {
diags.AddError("failed to load keys", err.Error())
return
}
o.Keys = types.SetValueMust(types.StringType, k)
}

func (o *PropertySet) Request(_ context.Context, _ *diag.Diagnostics) *apstra.PropertySetData {
return &apstra.PropertySetData{
Label: o.Label.ValueString(),
Values: []byte(o.Values.ValueString()),
Label: o.Name.ValueString(),
Values: []byte(o.Data.ValueString()),
}
}
21 changes: 14 additions & 7 deletions apstra/resource_property_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,14 @@ func (o *resourcePropertySet) Create(ctx context.Context, req resource.CreateReq
resp.Diagnostics.AddError("error creating new PropertySet", err.Error())
return
}
// Save the tag ID
plan.Id = types.StringValue(psid.String())
plan.Blueprints = types.SetNull(types.StringType)
k, err := utils.GetKeysFromJSON(plan.Data)
if err != nil {
resp.Diagnostics.AddError("failed to load keys", err.Error())
return
}
plan.Keys = types.SetValueMust(types.StringType, k)
// set state
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
Expand Down Expand Up @@ -95,8 +100,8 @@ func (o *resourcePropertySet) Read(ctx context.Context, req resource.ReadRequest
if resp.Diagnostics.HasError() {
return
}
if utils.JSONEqual(newstate.Values, state.Values, &resp.Diagnostics) {
newstate.Values = state.Values
if utils.JSONEqual(newstate.Data, state.Data, &resp.Diagnostics) {
newstate.Data = state.Data
}
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -141,13 +146,15 @@ func (o *resourcePropertySet) Update(ctx context.Context, req resource.UpdateReq
fmt.Sprintf("PropertySet with ID %q not found. This should not happen", plan.Id.ValueString()))
return
}
var d design.PropertySet
d.LoadApiData(ctx, api.Data, &resp.Diagnostics)
// save the old data
d := plan.Data
plan.LoadApiData(ctx, api.Data, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}

plan.Blueprints = d.Blueprints
if utils.JSONEqual(plan.Data, d, &resp.Diagnostics) {
plan.Data = d
}
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

Expand Down
21 changes: 21 additions & 0 deletions apstra/utils/compare_jsons.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"encoding/json"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"reflect"
Expand Down Expand Up @@ -40,3 +41,23 @@ func IsJSON(str types.String) bool {
err := json.Unmarshal([]byte(str.ValueString()), &m)
return err == nil
}

// GetKeysFromJSON returns a list of keys from a Json string
func GetKeysFromJSON(str types.String) ([]attr.Value, error) {
m := make(map[string]interface{})
err := json.Unmarshal([]byte(str.ValueString()), &m)
if err != nil {
return nil, err
}
return getKeysFromMap(m), nil
}

func getKeysFromMap(m map[string]interface{}) []attr.Value {
keys := make([]attr.Value, len(m))
i := 0
for k := range m {
keys[i] = types.StringValue(k)
i++
}
return keys
}
13 changes: 11 additions & 2 deletions docs/data-sources/property_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ output "apstra_property_set_report" {
name = v.name
data = jsondecode(v.data)
blueprints = v.blueprints
keys = v.keys
} }
}
################################################################################
# The output object above will produce something like the following:
# apstra_property_set_report = {
Expand All @@ -44,7 +44,11 @@ output "apstra_property_set_report" {
# "data" = {
# "nameserver1" = "10.155.191.252"
# "nameserver2" = "172.21.200.60"
# }
# },
# "keys" = toset([
# "nameserver1",
# "nameserver2",
# ])
# "name" = "nameservers"
# }
# "7d68daeb-b8f5-4512-9417-9e5812d87783" = {
Expand All @@ -57,6 +61,10 @@ output "apstra_property_set_report" {
# "snmp_collector_01" = "10.6.1.87/32"
# "snmp_collector_02" = "10.6.1.88/32"
# }
# "keys" = toset([
# "snmp_collector_01",
# "snmp_collector_02",
# ])
# "name" = "MUST_SNMP_D42"
# }
# }
Expand All @@ -75,3 +83,4 @@ output "apstra_property_set_report" {

- `blueprints` (Set of String) Set of blueprints that this Property Set might be associated with.
- `data` (String) A map of values in the Property Set in JSON format
- `keys` (Set of String) Set of keys defined in the Property Set.
10 changes: 9 additions & 1 deletion docs/data-sources/property_sets.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ output "apstra_property_set_report" {
# "data" = {
# "nameserver1" = "10.155.191.252"
# "nameserver2" = "172.21.200.60"
# }
# },
# "keys" = toset([
# "nameserver1",
# "nameserver2",
# ])
# "name" = "nameservers"
# }
# "7d68daeb-b8f5-4512-9417-9e5812d87783" = {
Expand All @@ -53,6 +57,10 @@ output "apstra_property_set_report" {
# "snmp_collector_01" = "10.6.1.87/32"
# "snmp_collector_02" = "10.6.1.88/32"
# }
# "keys" = toset([
# "snmp_collector_01",
# "snmp_collector_02",
# ])
# "name" = "MUST_SNMP_D42"
# }
# }
Expand Down
1 change: 1 addition & 0 deletions docs/resources/property_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ resource "apstra_property_set" "r" {

- `blueprints` (Set of String) Set of blueprints that this Property Set might be associated with.
- `id` (String) Populate this field to look up a Property Set by ID. Required when `name` is omitted.
- `keys` (Set of String) Set of keys defined in the Property Set.
14 changes: 11 additions & 3 deletions examples/data-sources/apstra_property_set/example.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ output "apstra_property_set_report" {
name = v.name
data = jsondecode(v.data)
blueprints = v.blueprints
keys = v.keys
} }
}

################################################################################
# The output object above will produce something like the following:
# apstra_property_set_report = {
Expand All @@ -27,7 +27,11 @@ output "apstra_property_set_report" {
# "data" = {
# "nameserver1" = "10.155.191.252"
# "nameserver2" = "172.21.200.60"
# }
# },
# "keys" = toset([
# "nameserver1",
# "nameserver2",
# ])
# "name" = "nameservers"
# }
# "7d68daeb-b8f5-4512-9417-9e5812d87783" = {
Expand All @@ -40,7 +44,11 @@ output "apstra_property_set_report" {
# "snmp_collector_01" = "10.6.1.87/32"
# "snmp_collector_02" = "10.6.1.88/32"
# }
# "keys" = toset([
# "snmp_collector_01",
# "snmp_collector_02",
# ])
# "name" = "MUST_SNMP_D42"
# }
# }
################################################################################
################################################################################
10 changes: 9 additions & 1 deletion examples/data-sources/apstra_property_sets/example.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ output "apstra_property_set_report" {
# "data" = {
# "nameserver1" = "10.155.191.252"
# "nameserver2" = "172.21.200.60"
# }
# },
# "keys" = toset([
# "nameserver1",
# "nameserver2",
# ])
# "name" = "nameservers"
# }
# "7d68daeb-b8f5-4512-9417-9e5812d87783" = {
Expand All @@ -39,6 +43,10 @@ output "apstra_property_set_report" {
# "snmp_collector_01" = "10.6.1.87/32"
# "snmp_collector_02" = "10.6.1.88/32"
# }
# "keys" = toset([
# "snmp_collector_01",
# "snmp_collector_02",
# ])
# "name" = "MUST_SNMP_D42"
# }
# }
Expand Down

0 comments on commit 220e145

Please sign in to comment.