Skip to content

Commit

Permalink
+ Groups Lookup Datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
kgibson-spotnana committed Mar 19, 2024
1 parent 5b2e29e commit 7d5b770
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 1 deletion.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21
toolchain go1.21.5

require (
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4-0.20240318201126-c808a5c26dc8
github.com/hashicorp/terraform-plugin-docs v0.17.0
github.com/hashicorp/terraform-plugin-framework v1.5.0
github.com/hashicorp/terraform-plugin-go v0.20.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4-0.20240318191421-d3910f0a1bda h1:sHY3nrRjG9KI1THihNJ6yfZquhfD0dBCIGVeWG2PIUs=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4-0.20240318191421-d3910f0a1bda/go.mod h1:9iUtBe/vjsO9xmFmarSdTM9BiQv9cqlwDu7yJc+bsVo=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4-0.20240318201126-c808a5c26dc8 h1:e9kALMnG3lEJfAtiPdGpODbk5i3bjf8/U3Ifpvbe8cE=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4-0.20240318201126-c808a5c26dc8/go.mod h1:9iUtBe/vjsO9xmFmarSdTM9BiQv9cqlwDu7yJc+bsVo=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4 h1:VC86V57q2aMNg/lxl6Nsi7wz4BJjcoIq57nUbbage0Q=
github.com/Spotnana-Tech/sec-jumpcloud-client-go v1.0.4/go.mod h1:9iUtBe/vjsO9xmFmarSdTM9BiQv9cqlwDu7yJc+bsVo=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func (p *jumpcloudProvider) Configure(ctx context.Context, req provider.Configur
func (p *jumpcloudProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewjcUserGroupDataSource,
NewjcUserGroupLookupDataSource,
NewjcAppsDataSource,
}
}
Expand Down
193 changes: 193 additions & 0 deletions internal/provider/usergroups_lookup_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package provider

import (
"context"
"fmt"
"github.com/Spotnana-Tech/sec-jumpcloud-client-go"
"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/path"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &jcUserGroupDataLookupSource{}
_ datasource.DataSourceWithConfigure = &jcUserGroupDataLookupSource{}
)

// jcUserGroupsLookupModel maps the provider schema data to a Go type.
type jcUserGroupsLookupModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Type types.String `tfsdk:"type"`
Members types.Set `tfsdk:"members"`
}

// jcUserGroupsDataSourceModel maps the data source schema data.
type jcUserGroupsLookupDataSourceModel struct {
UserGroups []jcUserGroupsLookupModel `tfsdk:"groups"`
Name types.String `tfsdk:"name"`
Limit types.Int64 `tfsdk:"limit"`
}

// NewjcUserGroupLookupDataSource is a helper function to simplify the provider implementation.
func NewjcUserGroupLookupDataSource() datasource.DataSource {
return &jcUserGroupDataLookupSource{}
}

// jcUserGroupDataLookupSource is the data source implementation.
// This struct accepts a client pointer to the JumpCloud Go client so terraform can make its changes to the system.
type jcUserGroupDataLookupSource struct {
client *jumpcloud.Client
}

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

// Schema defines the schema for the data source.
func (d *jcUserGroupDataLookupSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"groups": schema.ListNestedAttribute{
Computed: true,
Description: "A list of Jumpcloud User Groups",
MarkdownDescription: "A list of Jumpcloud User Groups",
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
Description: "The ID of the User Group",
MarkdownDescription: "The ID of the User Group",
},
"name": schema.StringAttribute{
Computed: true,
Description: "The Name of the User Group",
MarkdownDescription: "The Name of the User Group",
},
"description": schema.StringAttribute{
Computed: true,
},
"type": schema.StringAttribute{
Computed: true,
Description: "Types can be user_group or system_group",
MarkdownDescription: "Types can be user_group or system_group",
},
"members": schema.SetAttribute{
Computed: true,
Description: "The members of the User Group",
MarkdownDescription: "The members of the User Group",
ElementType: types.StringType,
},
},
},
},
"name": schema.StringAttribute{
Required: true,
Computed: false,
Description: "The name to filter on",
MarkdownDescription: "The name to filter on",
},
"limit": schema.Int64Attribute{
Optional: true,
Computed: false,
Description: "The limit of results to return",
MarkdownDescription: "The limit of results to return",
},
},
}
}

// Read refreshes the Terraform state with the latest data.
func (d *jcUserGroupDataLookupSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Get all user groups
var state jcUserGroupsLookupDataSourceModel
var name string
var limit int
//diags := req.State.Get(ctx, &state)
diags := req.Config.Get(ctx, &state)

Check failure on line 113 in internal/provider/usergroups_lookup_data_source.go

View workflow job for this annotation

GitHub Actions / Build

ineffectual assignment to diags (ineffassign)
diags = req.Config.GetAttribute(ctx, path.Root("name"), &name)

Check failure on line 114 in internal/provider/usergroups_lookup_data_source.go

View workflow job for this annotation

GitHub Actions / Build

ineffectual assignment to diags (ineffassign)
diags = req.Config.GetAttribute(ctx, path.Root("limit"), &limit)

Check failure on line 115 in internal/provider/usergroups_lookup_data_source.go

View workflow job for this annotation

GitHub Actions / Build

ineffectual assignment to diags (ineffassign)
tflog.Info(ctx, fmt.Sprintf("Request: name %s, limit %d", name, limit))
if limit == 0 {
limit = 5
}
tflog.Info(ctx, fmt.Sprintf("Filters: %s : %v",
name,
limit,
),
)

groups, err := d.client.SearchUserGroups(
"name",
name,
limit,
)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Read Jumpcloud User Groups",
err.Error(),
)
return
}
tflog.Info(ctx, fmt.Sprintf("Read Jumpcloud User Groups: %v", len(groups)))
if len(groups) == 0 {
resp.Diagnostics.AddError(
"Unable to Read Jumpcloud User Groups",
"No user groups found",
)
return
}
// Map response to state
for _, group := range groups {
// Get the members
var memberEmails []attr.Value // This is the terraform structure requirement
members, _ := d.client.GetGroupMembers(group.ID)
for _, member := range members {
email, _ := d.client.GetUserEmailFromID(member.To.ID)
memberEmails = append(memberEmails, types.StringValue(email))
}
returnedMembers, _ := types.SetValue(types.StringType, memberEmails)
jcUserGroupsLookupState := jcUserGroupsLookupModel{
ID: types.StringValue(group.ID),
Name: types.StringValue(group.Name),
Description: types.StringValue(group.Description),
Type: types.StringValue(group.Type),
Members: returnedMembers,
}
state.UserGroups = append(state.UserGroups, jcUserGroupsLookupState)
}
state.Limit = types.Int64Value(int64(limit))
state.Name = types.StringValue(name)
// Set state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return

}
}

// Configure adds the provider configured client to the data source.
func (d *jcUserGroupDataLookupSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

// This is where we import our client for this type of data source
client, ok := req.ProviderData.(*jumpcloud.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *hashicups.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = client
}

0 comments on commit 7d5b770

Please sign in to comment.