Skip to content

Commit

Permalink
Add team_mappings resource
Browse files Browse the repository at this point in the history
  • Loading branch information
Shawn Castrianni authored and Shawn Castrianni committed Jun 18, 2023
1 parent 96ae8f4 commit cde1f09
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 6 deletions.
29 changes: 29 additions & 0 deletions docs/resources/team_mappings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
subcategory: "Identity Management"
---
# Resource: konnect_team_mappings
Represents the mappings between an external identity provider group and a Konnect team
## Example usage
```hcl
resource "konnect_team" "Team" {
name = "Test"
description = "testing"
}
resource "konnect_team_mappings" "example" {
mapping {
group = "external IdP group"
team_ids = [
data.konnect_team.Team.id
]
}
}
```
## Argument Reference
* `mapping` - **(Optional, set{mapping})** Configuration block for a mapping. Can be specified multiple times for each mapping. Each block supports the fields documented below.
### mapping
* `group` - **(Required, String)** Identifier of an IdP group that is contained with OIDC ID token for groups claim
* `team_ids` - **(Required, List of String)** Konnect teams that should map to this group.
## Attribute Reference
* `id` - **(String)** Always equal to `team-mappings`
## Import
Team mappings can be imported using a proper value of `id` as described above
3 changes: 2 additions & 1 deletion konnect/client/authentication_settings.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package client

const (
AuthenticationSettingsPath = "authentication-settings"
AuthenticationSettingsId = "authentication-settings"
AuthenticationSettingsPath = AuthenticationSettingsId
)

type AuthenticationSettings struct {
Expand Down
3 changes: 2 additions & 1 deletion konnect/client/identity_provider.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package client

const (
IdentityProviderPath = "identity-provider"
IdentityProviderId = "identity-provider"
IdentityProviderPath = IdentityProviderId
EmailClaim = "email"
NameClaim = "name"
GroupsClaim = "groups"
Expand Down
15 changes: 15 additions & 0 deletions konnect/client/team_mappings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package client

const (
TeamMappingsId = "team-mappings"
TeamMappingsPath = IdentityProviderPath + "/" + TeamMappingsId
)

type TeamMapping struct {
Group string `json:"group,omitempty"`
TeamIds []string `json:"team_ids,omitempty"`
}
type TeamMappings struct {
MappingsRead []TeamMapping `json:"data,omitempty"`
MappingsWrite []TeamMapping `json:"mappings,omitempty"`
}
1 change: 1 addition & 0 deletions konnect/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func Provider() *schema.Provider {
"konnect_team": resourceTeam(),
"konnect_team_user": resourceTeamUser(),
"konnect_team_role": resourceTeamRole(),
"konnect_team_mappings": resourceTeamMappings(),
"konnect_user_role": resourceUserRole(),
"konnect_service": resourceService(),
"konnect_route": resourceRoute(),
Expand Down
5 changes: 3 additions & 2 deletions konnect/resource_authentication_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,16 @@ func resourceAuthenticationSettingsCreate(ctx context.Context, d *schema.Resourc
d.SetId("")
return diag.FromErr(err)
}
d.SetId(client.AuthenticationSettingsId)
return diags
}

func resourceAuthenticationSettingsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
c := m.(*client.Client)
if d.Id() != client.AuthenticationSettingsPath {
if d.Id() != client.AuthenticationSettingsId {
d.SetId("")
return diag.FromErr(fmt.Errorf("Id must be equal to %s", client.AuthenticationSettingsPath))
return diag.FromErr(fmt.Errorf("Id must be equal to %s", client.AuthenticationSettingsId))
}
requestPath := fmt.Sprintf(client.AuthenticationSettingsPath)
body, err := c.HttpRequest(ctx, false, http.MethodGet, requestPath, nil, nil, &bytes.Buffer{})
Expand Down
5 changes: 3 additions & 2 deletions konnect/resource_identity_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,16 @@ func resourceIdentityProviderCreate(ctx context.Context, d *schema.ResourceData,
d.SetId("")
return diag.FromErr(err)
}
d.SetId(client.IdentityProviderId)
return diags
}

func resourceIdentityProviderRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
c := m.(*client.Client)
if d.Id() != client.IdentityProviderPath {
if d.Id() != client.IdentityProviderId {
d.SetId("")
return diag.FromErr(fmt.Errorf("Id must be equal to %s", client.IdentityProviderPath))
return diag.FromErr(fmt.Errorf("Id must be equal to %s", client.IdentityProviderId))
}
requestPath := fmt.Sprintf(client.IdentityProviderPath)
body, err := c.HttpRequest(ctx, false, http.MethodGet, requestPath, nil, nil, &bytes.Buffer{})
Expand Down
163 changes: 163 additions & 0 deletions konnect/resource_team_mappings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package konnect

import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/go-http-utils/headers"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scastria/terraform-provider-konnect/konnect/client"
"net/http"
)

func resourceTeamMappings() *schema.Resource {
return &schema.Resource{
CreateContext: resourceTeamMappingsCreate,
ReadContext: resourceTeamMappingsRead,
UpdateContext: resourceTeamMappingsUpdate,
DeleteContext: resourceTeamMappingsDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"mapping": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"group": {
Type: schema.TypeString,
Required: true,
},
"team_ids": {
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
}
}

func fillTeamMappings(c *client.TeamMappings, d *schema.ResourceData) {
konnectMappings, ok := d.GetOk("mapping")
if ok {
c.MappingsRead = []client.TeamMapping{}
for _, item := range konnectMappings.(*schema.Set).List() {
itemMap := item.(map[string]interface{})
itemGroup := itemMap["group"].(string)
itemTeamIdsList := itemMap["team_ids"].(*schema.Set).List()
var itemTeamIds []string
for _, value := range itemTeamIdsList {
itemTeamIds = append(itemTeamIds, value.(string))
}
mapping := client.TeamMapping{
Group: itemGroup,
TeamIds: itemTeamIds,
}
c.MappingsRead = append(c.MappingsRead, mapping)
}
} else {
c.MappingsRead = nil
}
c.MappingsWrite = c.MappingsRead
}

func fillResourceDataFromTeamMappings(c *client.TeamMappings, d *schema.ResourceData) {
var konnectMappings []map[string]interface{}
konnectMappings = nil
if c.MappingsWrite != nil {
c.MappingsRead = c.MappingsWrite
}
if c.MappingsRead != nil {
for _, mapping := range c.MappingsRead {
itemMap := map[string]interface{}{}
itemMap["group"] = mapping.Group
itemMap["team_ids"] = mapping.TeamIds
konnectMappings = append(konnectMappings, itemMap)
}
}
d.Set("mapping", konnectMappings)
}

func resourceTeamMappingsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
err := resourceTeamMappingsCreateUpdate(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
d.SetId(client.TeamMappingsId)
return diags
}

func resourceTeamMappingsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
c := m.(*client.Client)
if d.Id() != client.TeamMappingsId {
d.SetId("")
return diag.FromErr(fmt.Errorf("Id must be equal to %s", client.TeamMappingsId))
}
requestPath := fmt.Sprintf(client.TeamMappingsPath)
body, err := c.HttpRequest(ctx, false, http.MethodGet, requestPath, nil, nil, &bytes.Buffer{})
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
retVal := &client.TeamMappings{}
err = json.NewDecoder(body).Decode(retVal)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
fillResourceDataFromTeamMappings(retVal, d)
return diags
}

func resourceTeamMappingsCreateUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) error {
c := m.(*client.Client)
buf := bytes.Buffer{}
upTeamMappings := client.TeamMappings{}
fillTeamMappings(&upTeamMappings, d)
//When writing, Konnect API uses mappings from MappingsWrite
upTeamMappings.MappingsRead = nil
err := json.NewEncoder(&buf).Encode(upTeamMappings)
if err != nil {
return err
}
requestPath := fmt.Sprintf(client.TeamMappingsPath)
requestHeaders := http.Header{
headers.ContentType: []string{client.ApplicationJson},
}
body, err := c.HttpRequest(ctx, false, http.MethodPut, requestPath, nil, requestHeaders, &buf)
if err != nil {
return err
}
retVal := &client.TeamMappings{}
err = json.NewDecoder(body).Decode(retVal)
if err != nil {
return err
}
fillResourceDataFromTeamMappings(retVal, d)
return nil
}

func resourceTeamMappingsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
err := resourceTeamMappingsCreateUpdate(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
return diags
}

func resourceTeamMappingsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
d.SetId("")
return diag.Diagnostics{}
}

0 comments on commit cde1f09

Please sign in to comment.