Skip to content

Commit

Permalink
Merge pull request #13 from Juniper/data-source-agent-profiles-filters
Browse files Browse the repository at this point in the history
Data source agent profiles filters
  • Loading branch information
chrismarget-j authored Apr 11, 2023
2 parents 6b4d909 + f5e6c5e commit 2e03544
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 18 deletions.
72 changes: 60 additions & 12 deletions apstra/data_source_agent_profiles.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package tfapstra

import (
"github.com/Juniper/apstra-go-sdk/apstra"
"context"
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"terraform-provider-apstra/apstra/utils"
)

var _ datasource.DataSourceWithConfigure = &dataSourceAgentProfiles{}
Expand All @@ -31,34 +34,79 @@ func (o *dataSourceAgentProfiles) Schema(_ context.Context, _ datasource.SchemaR
Computed: true,
ElementType: types.StringType,
},
"platform": schema.StringAttribute{
MarkdownDescription: "Filter to select only Agent Profiles for the specified platform.",
Optional: true,
Validators: []validator.String{stringvalidator.OneOf(utils.AgentProfilePlatforms()...)},
},
"has_credentials": schema.BoolAttribute{
MarkdownDescription: "Filter to select only Agent Profiles configured with (or without) Username and Password.",
Optional: true,
},
},
}
}

func (o *dataSourceAgentProfiles) Read(ctx context.Context, _ datasource.ReadRequest, resp *datasource.ReadResponse) {
func (o *dataSourceAgentProfiles) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
if o.client == nil {
resp.Diagnostics.AddError(errDataSourceUnconfiguredSummary, errDatasourceUnconfiguredDetail)
return
}

ids, err := o.client.ListAgentProfileIds(ctx)
if err != nil {
resp.Diagnostics.AddError("Error retrieving Agent Profile IDs", err.Error())
config := struct {
Ids types.Set `tfsdk:"ids"`
Platform types.String `tfsdk:"platform"`
HasCredentials types.Bool `tfsdk:"has_credentials"`
}{}

resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
if resp.Diagnostics.HasError() {
return
}

idSet, diags := types.SetValueFrom(ctx, types.StringType, ids)
var err error

// both of these slices start as nil...
var agentProfileIds []apstra.ObjectId
var agentProfiles []apstra.AgentProfile

// one of the slices from above will get populated, depending on whether the user included filters...
if config.Ids.IsNull() && config.Platform.IsNull() && config.HasCredentials.IsNull() {
agentProfileIds, err = o.client.ListAgentProfileIds(ctx)
if err != nil {
resp.Diagnostics.AddError("Error retrieving Agent Profile IDs", err.Error())
return
}
} else {
agentProfiles, err = o.client.GetAllAgentProfiles(ctx)
if err != nil {
resp.Diagnostics.AddError("Error retrieving Agent Profile IDs", err.Error())
return
}
}

// loop over agentProfiles unconditionally. If anything's in here, it's interesting.
for _, profile := range agentProfiles {
if !config.HasCredentials.IsNull() && config.HasCredentials.ValueBool() != profile.HasCredentials() {
continue
}

if !config.Platform.IsNull() && config.Platform.ValueString() != profile.Platform {
continue
}

agentProfileIds = append(agentProfileIds, profile.Id)
}

// convert agentProfileIds ([]apstra.ObjectId) to a types.Set of types.String
idSet, diags := types.SetValueFrom(ctx, types.StringType, agentProfileIds)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

// create new state object
var state struct {
Ids types.Set `tfsdk:"ids"`
}
state.Ids = idSet
config.Ids = idSet

// set state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
}
8 changes: 2 additions & 6 deletions apstra/devices_agent_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,8 @@ func (o agentProfile) resourceAttributes() map[string]resourceSchema.Attribute {
MarkdownDescription: "Indicates the platform supported by the Agent Profile.",
Computed: true,
Optional: true,
Validators: []validator.String{stringvalidator.OneOf(
apstra.AgentPlatformNXOS.String(),
apstra.AgentPlatformJunos.String(),
apstra.AgentPlatformEOS.String(),
)},
Default: stringdefault.StaticString(apstra.AgentPlatformJunos.String()),
Validators: []validator.String{stringvalidator.OneOf(utils.AgentProfilePlatforms()...)},
Default: stringdefault.StaticString(apstra.AgentPlatformJunos.String()),
},
"packages": resourceSchema.MapAttribute{
MarkdownDescription: "List of [packages](https://www.juniper.net/documentation/us/en/software/apstra4.1/apstra-user-guide/topics/topic-map/packages.html) " +
Expand Down
11 changes: 11 additions & 0 deletions apstra/utils/agent_profiles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package utils

import "github.com/Juniper/apstra-go-sdk/apstra"

func AgentProfilePlatforms() []string {
return []string{
apstra.AgentPlatformNXOS.String(),
apstra.AgentPlatformJunos.String(),
apstra.AgentPlatformEOS.String(),
}
}
5 changes: 5 additions & 0 deletions docs/data-sources/agent_profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ output "agent_profiles_missing_credentials" {
<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `has_credentials` (Boolean) Filter to select only Agent Profiles configured with (or without) Username and Password.
- `platform` (String) Filter to select only Agent Profiles for the specified platform.

### Read-Only

- `ids` (Set of String) A set of Apstra object ID numbers.

0 comments on commit 2e03544

Please sign in to comment.