Skip to content

Commit

Permalink
feat: Add JAAS group data source
Browse files Browse the repository at this point in the history
  • Loading branch information
pkulik0 committed Oct 8, 2024
1 parent 079a111 commit 3407668
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 18 deletions.
24 changes: 24 additions & 0 deletions docs/data-sources/jaas_group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "juju_jaas_group Data Source - terraform-provider-juju"
subcategory: ""
description: |-
A data source representing a Juju JAAS Group.
---

# juju_jaas_group (Data Source)

A data source representing a Juju JAAS Group.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) The name of the group.

### Read-Only

- `uuid` (String) The UUID of the group.
22 changes: 15 additions & 7 deletions internal/juju/jaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (jc *jaasClient) ReadRelations(ctx context.Context, tuple *JaasTuple) ([]Ja
}

// AddGroup attempts to create a new group with the provided name.
func (jc *jaasClient) AddGroup(ctx context.Context, name string) (string, error) {
func (jc *jaasClient) AddGroup(name string) (string, error) {
conn, err := jc.GetConnection(nil)
if err != nil {
return "", err
Expand All @@ -167,25 +167,33 @@ func (jc *jaasClient) AddGroup(ctx context.Context, name string) (string, error)
return resp.UUID, nil
}

// ReadGroup attempts to read a group that matches the provided UUID.
func (jc *jaasClient) ReadGroup(ctx context.Context, uuid string) (*JaasGroup, error) {
// ReadGroupByUUID attempts to read a group that matches the provided UUID.
func (jc *jaasClient) ReadGroupByUUID(uuid string) (*JaasGroup, error) {
return jc.readGroup(&params.GetGroupRequest{UUID: uuid})
}

// ReadGroupByName attempts to read a group that matches the provided name.
func (jc *jaasClient) ReadGroupByName(name string) (*JaasGroup, error) {
return jc.readGroup(&params.GetGroupRequest{Name: name})
}

func (jc *jaasClient) readGroup(req *params.GetGroupRequest) (*JaasGroup, error) {
conn, err := jc.GetConnection(nil)
if err != nil {
return nil, err
}
defer func() { _ = conn.Close() }()

client := jc.getJaasApiClient(conn)
req := params.GetGroupRequest{UUID: uuid}
resp, err := client.GetGroup(&req)
resp, err := client.GetGroup(req)
if err != nil {
return nil, err
}
return &JaasGroup{Name: resp.Name, UUID: resp.UUID}, nil
}

// RenameGroup attempts to rename a group that matches the provided name.
func (jc *jaasClient) RenameGroup(ctx context.Context, name, newName string) error {
func (jc *jaasClient) RenameGroup(name, newName string) error {
conn, err := jc.GetConnection(nil)
if err != nil {
return err
Expand All @@ -198,7 +206,7 @@ func (jc *jaasClient) RenameGroup(ctx context.Context, name, newName string) err
}

// RemoveGroup attempts to remove a group that matches the provided name.
func (jc *jaasClient) RemoveGroup(ctx context.Context, name string) error {
func (jc *jaasClient) RemoveGroup(name string) error {
conn, err := jc.GetConnection(nil)
if err != nil {
return err
Expand Down
10 changes: 5 additions & 5 deletions internal/juju/jaas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (s *JaasSuite) TestAddGroup() {
s.mockJaasClient.EXPECT().AddGroup(req).Return(resp, nil)

client := s.getJaasClient()
uuid, err := client.AddGroup(context.Background(), name)
uuid, err := client.AddGroup(name)
s.Require().NoError(err)
s.Require().Equal(resp.UUID, uuid)
}
Expand All @@ -179,7 +179,7 @@ func (s *JaasSuite) TestGetGroup() {
s.mockJaasClient.EXPECT().GetGroup(req).Return(resp, nil)

client := s.getJaasClient()
gotGroup, err := client.ReadGroup(context.Background(), uuid)
gotGroup, err := client.ReadGroupByUUID(uuid)
s.Require().NoError(err)
s.Require().Equal(*gotGroup, JaasGroup{UUID: uuid, Name: name})
}
Expand All @@ -193,7 +193,7 @@ func (s *JaasSuite) TestGetGroupNotFound() {
s.mockJaasClient.EXPECT().GetGroup(req).Return(params.GetGroupResponse{}, errors.New("group not found"))

client := s.getJaasClient()
gotGroup, err := client.ReadGroup(context.Background(), uuid)
gotGroup, err := client.ReadGroupByUUID(uuid)
s.Require().Error(err)
s.Require().Nil(gotGroup)
}
Expand All @@ -207,7 +207,7 @@ func (s *JaasSuite) TestRenameGroup() {
s.mockJaasClient.EXPECT().RenameGroup(req).Return(nil)

client := s.getJaasClient()
err := client.RenameGroup(context.Background(), name, newName)
err := client.RenameGroup(name, newName)
s.Require().NoError(err)
}

Expand All @@ -219,7 +219,7 @@ func (s *JaasSuite) TestRemoveGroup() {
s.mockJaasClient.EXPECT().RemoveGroup(req).Return(nil)

client := s.getJaasClient()
err := client.RemoveGroup(context.Background(), name)
err := client.RemoveGroup(name)
s.Require().NoError(err)
}

Expand Down
114 changes: 114 additions & 0 deletions internal/provider/data_source_jaas_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2024 Canonical Ltd.
// Licensed under the Apache License, Version 2.0, see LICENCE file for details.

package provider

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/juju/terraform-provider-juju/internal/juju"
)

type jaasGroupDataSource struct {
client *juju.Client

// subCtx is the context created with the new tflog subsystem for applications.
subCtx context.Context
}

// NewJAASGroupDataSource returns a new JAAS group data source instance.
func NewJAASGroupDataSource() datasource.DataSource {
return &jaasGroupDataSource{}
}

type jaasGroupDataSourceModel struct {
Name types.String `tfsdk:"name"`
UUID types.String `tfsdk:"uuid"`
}

// Metadata returns the metadata for the JAAS group data source.
func (d *jaasGroupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_jaas_group"
}

// Schema defines the schema for JAAS groups.
func (d *jaasGroupDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "A data source representing a Juju JAAS Group.",
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Description: "The name of the group.",
Required: true,
},
"uuid": schema.StringAttribute{
Description: "The UUID of the group.",
Computed: true,
},
},
}
}

// Configure sets up the JAAS group data source with the provider data.
func (d *jaasGroupDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*juju.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = client
d.subCtx = tflog.NewSubsystem(ctx, LogDataSourceJAASGroup)
}

// Read updates the group data source with the latest data from JAAS.
func (d *jaasGroupDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
// Prevent panic if the provider has not been configured.
if d.client == nil {
addDSClientNotConfiguredError(&resp.Diagnostics, "jaas-group")
return
}

var data jaasGroupDataSourceModel

// Read Terraform configuration state into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

// Update the group with the latest data from JAAS
group, err := d.client.Jaas.ReadGroupByName(data.Name.String())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read group, got error: %v", err))
return
}
data.UUID = types.StringValue(group.UUID)
d.trace(fmt.Sprintf("read group %q data source", data.Name))

// Save the updated group back to the state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func (d *jaasGroupDataSource) trace(msg string, additionalFields ...map[string]interface{}) {
if d.subCtx == nil {
return
}

//SubsystemTrace(subCtx, "datasource-jaas-group", "hello, world", map[string]interface{}{"foo": 123})
// Output:
// {"@level":"trace","@message":"hello, world","@module":"juju.datasource-jaas-group","foo":123}
tflog.SubsystemTrace(d.subCtx, LogDataSourceJAASGroup, msg, additionalFields...)
}
49 changes: 49 additions & 0 deletions internal/provider/data_source_jaas_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2024 Canonical Ltd.
// Licensed under the Apache License, Version 2.0, see LICENCE file for details.

package provider

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"

internaltesting "github.com/juju/terraform-provider-juju/internal/testing"
)

func TestAcc_DataSourceJAASGroup(t *testing.T) {
OnlyTestAgainstJAAS(t)
groupName := acctest.RandomWithPrefix("tf-jaas-group")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: frameworkProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceJAASGroup(groupName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.juju_jaas_group.test", "name", groupName),
resource.TestCheckResourceAttrSet("data.juju_jaas_group.test", "uuid"),
resource.TestCheckResourceAttrPair("juju_jaas_group.test", "uuid", "data.juju_jaas_group.test", "uuid"),
),
},
},
})
}

func testAccDataSourceJAASGroup(name string) string {
return internaltesting.GetStringFromTemplateWithData(
"testAccDataSourceJAASGroup",
`
resource "juju_jaas_group" "test" {
name = "{{ .Name }}"
}
data "juju_jaas_group" "test" {
name = juju_jaas_group.test.name
}
`, internaltesting.TemplateData{
"Name": name,
})
}
2 changes: 2 additions & 0 deletions internal/provider/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const (
LogResourceSecret = "resource-secret"
LogResourceAccessSecret = "resource-access-secret"

LogDataSourceJAASGroup = "datasource-jaas-group"

LogResourceJAASAccessModel = "resource-jaas-access-model"
LogResourceJAASAccessCloud = "resource-jaas-access-cloud"
LogResourceJAASAccessGroup = "resource-jaas-access-group"
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ func (p *jujuProvider) DataSources(_ context.Context) []func() datasource.DataSo
func() datasource.DataSource { return NewModelDataSource() },
func() datasource.DataSource { return NewOfferDataSource() },
func() datasource.DataSource { return NewSecretDataSource() },
func() datasource.DataSource { return NewJAASGroupDataSource() },
}
}

Expand Down
8 changes: 4 additions & 4 deletions internal/provider/resource_jaas_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (resource *jaasGroupResource) Create(ctx context.Context, req resource.Crea
}

// Add the group to JAAS
uuid, err := resource.client.Jaas.AddGroup(ctx, plan.Name.ValueString())
uuid, err := resource.client.Jaas.AddGroup(plan.Name.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to add group %q, got error: %s", plan.Name.ValueString(), err))
return
Expand All @@ -133,7 +133,7 @@ func (resource *jaasGroupResource) Read(ctx context.Context, req resource.ReadRe
}

// Read the group from JAAS
group, err := resource.client.Jaas.ReadGroup(ctx, state.UUID.ValueString())
group, err := resource.client.Jaas.ReadGroupByUUID(state.UUID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get group %q, got error: %s", state.Name.ValueString(), err))
return
Expand Down Expand Up @@ -172,7 +172,7 @@ func (resource *jaasGroupResource) Update(ctx context.Context, req resource.Upda
}

// Rename the group in JAAS
err := resource.client.Jaas.RenameGroup(ctx, state.Name.ValueString(), plan.Name.ValueString())
err := resource.client.Jaas.RenameGroup(state.Name.ValueString(), plan.Name.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to rename group %q to %q, got error: %s", state.Name.ValueString(), plan.Name.ValueString(), err))
return
Expand All @@ -199,7 +199,7 @@ func (resource *jaasGroupResource) Delete(ctx context.Context, req resource.Dele
}

// Delete the group from JAAS
err := resource.client.Jaas.RemoveGroup(ctx, state.Name.ValueString())
err := resource.client.Jaas.RemoveGroup(state.Name.ValueString())
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to remove group %q, got error: %s", state.Name.ValueString(), err))
return
Expand Down
3 changes: 1 addition & 2 deletions internal/provider/resource_jaas_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package provider

import (
"context"
"errors"
"fmt"
"regexp"
Expand Down Expand Up @@ -77,7 +76,7 @@ func testAccCheckJaasGroupExists(resourceName string, checkExists bool) resource
return errors.New("No group uuid is set")
}

_, err := TestClient.Jaas.ReadGroup(context.Background(), uuid)
_, err := TestClient.Jaas.ReadGroupByUUID(uuid)
if checkExists && err != nil {
return fmt.Errorf("Group with uuid %q does not exist", uuid)
} else if !checkExists && err == nil {
Expand Down

0 comments on commit 3407668

Please sign in to comment.