Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new okta_app_saml_app_settings resource #692

Merged
merged 2 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/okta_app_saml_app_settings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# okta_app_saml_app_settings

This resource represents App Settings of an Okta SAML Application. For more information see the [API docs](https://developer.okta.com/docs/api/resources/apps#add-custom-saml-application)

- Example [can be found here](./preconfigured.tf)
21 changes: 21 additions & 0 deletions examples/okta_app_saml_app_settings/preconfigured.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "okta_app_saml" "test" {
preconfigured_app = "amazon_aws"
label = "testAcc_replace_with_uuid"
status = "ACTIVE"
}

resource "okta_app_saml_app_settings" "test" {
app_id = okta_app_saml.test.id
settings = jsonencode(
{
"appFilter" : "okta",
"awsEnvironmentType" : "aws.amazon",
"groupFilter" : "aws_(?{{accountid}}\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\-_]+)",
"joinAllRoles" : false,
"loginURL" : "https://console.aws.amazon.com/ec2/home",
"roleValuePattern" : "arn:aws:iam::$${accountid}:saml-provider/OKTA,arn:aws:iam::$${accountid}:role/$${role}",
"sessionDuration" : 7600,
"useGroupMapping" : false
}
)
}
21 changes: 21 additions & 0 deletions examples/okta_app_saml_app_settings/preconfigured_updated.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "okta_app_saml" "test" {
preconfigured_app = "amazon_aws"
label = "testAcc_replace_with_uuid"
status = "ACTIVE"
}

resource "okta_app_saml_app_settings" "test" {
app_id = okta_app_saml.test.id
settings = jsonencode(
{
"appFilter" : "okta",
"awsEnvironmentType" : "aws.amazon",
"groupFilter" : "aws_(?{{accountid}}\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\-_]+)",
"joinAllRoles" : false,
"loginURL" : "https://console.aws.amazon.com/ec2/home",
"roleValuePattern" : "arn:aws:iam::$${accountid}:saml-provider/OKTA,arn:aws:iam::$${accountid}:role/$${role}",
"sessionDuration" : 3200,
"useGroupMapping" : false
}
)
}
2 changes: 1 addition & 1 deletion okta/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func buildAppSettings(d *schema.ResourceData) *okta.ApplicationSettingsApplicati
if appSettings, ok := d.GetOk("app_settings_json"); ok {
payload := map[string]interface{}{}
_ = json.Unmarshal([]byte(appSettings.(string)), &payload)
settings = okta.ApplicationSettingsApplication(payload)
settings = payload
}
return &settings
}
Expand Down
2 changes: 2 additions & 0 deletions okta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
appOAuthAPIScope = "okta_app_oauth_api_scope"
appOAuthRedirectURI = "okta_app_oauth_redirect_uri"
appSaml = "okta_app_saml"
appSamlAppSettings = "okta_app_saml_app_settings"
appSecurePasswordStore = "okta_app_secure_password_store"
appSwa = "okta_app_swa"
appSharedCredentials = "okta_app_shared_credentials"
Expand Down Expand Up @@ -199,6 +200,7 @@ func Provider() *schema.Provider {
appOAuthAPIScope: resourceAppOAuthAPIScope(),
appOAuthRedirectURI: resourceAppOAuthRedirectURI(),
appSaml: resourceAppSaml(),
appSamlAppSettings: resourceAppSamlAppSettings(),
appSecurePasswordStore: resourceAppSecurePasswordStore(),
appSwa: resourceAppSwa(),
appSharedCredentials: resourceAppSharedCredentials(),
Expand Down
1 change: 1 addition & 0 deletions okta/provider_sweeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestMain(m *testing.M) {
setupSweeper(networkZone, sweepNetworkZones)
setupSweeper(inlineHook, sweepInlineHooks)
setupSweeper(userType, sweepUserTypes)
setupSweeper(behavior, sweepBehaviors)

// add zones sweeper
resource.TestMain(m)
Expand Down
105 changes: 105 additions & 0 deletions okta/resource_okta_app_saml_app_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package okta

import (
"context"
"encoding/json"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/okta/okta-sdk-golang/v2/okta"
)

func resourceAppSamlAppSettings() *schema.Resource {
return &schema.Resource{
CreateContext: resourceAppSamlSettingsCreate,
ReadContext: resourceAppSamlSettingsRead,
UpdateContext: resourceAppSamlSettingsUpdate,
DeleteContext: resourceAppSamlSettingsDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"app_id": {
Type: schema.TypeString,
Required: true,
Description: "Application ID",
ForceNew: true,
},
"settings": {
Type: schema.TypeString,
Required: true,
Description: "Application settings in JSON format",
ValidateDiagFunc: stringIsJSON,
StateFunc: normalizeDataJSON,
},
},
}
}

func resourceAppSamlSettingsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
id, err := updateOrCreateAppSettings(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
d.SetId(id)
return resourceAppSamlSettingsRead(ctx, d, m)
}

func resourceAppSamlSettingsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
app := okta.NewSamlApplication()
err := fetchApp(ctx, d, m, app)
if err != nil {
return diag.Errorf("failed to get SAML application: %v", err)
}
if app.Id == "" {
d.SetId("")
return nil
}
flatMap := map[string]interface{}{}
for key, val := range *app.Settings.App {
if str, ok := val.(string); ok {
if str != "" {
flatMap[key] = str
}
} else if val != nil {
flatMap[key] = val
}
}
payload, _ := json.Marshal(flatMap)
_ = d.Set("settings", string(payload))
_ = d.Set("app_id", app.Id)
return nil
}

func resourceAppSamlSettingsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
_, err := updateOrCreateAppSettings(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
return resourceAppSamlSettingsRead(ctx, d, m)
}

func updateOrCreateAppSettings(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
app := okta.NewSamlApplication()
appID := d.Get("app_id").(string)
err := fetchAppByID(ctx, appID, m, app)
if err != nil {
return "", fmt.Errorf("failed to get SAML application: %v", err)
}
if app.Id == "" {
return "", fmt.Errorf("application with id %s does not exist", appID)
}
settings := make(okta.ApplicationSettingsApplication)
_ = json.Unmarshal([]byte(d.Get("settings").(string)), &settings)
app.Settings.App = &settings
_, _, err = getOktaClientFromMetadata(m).Application.UpdateApplication(ctx, appID, app)
if err != nil {
return "", fmt.Errorf("failed to update SAML application's settings: %v", err)
}
return app.Id, nil
}

func resourceAppSamlSettingsDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
return nil
}
73 changes: 73 additions & 0 deletions okta/resource_okta_app_saml_app_settings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package okta

import (
"context"
"encoding/json"
"fmt"
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/okta/okta-sdk-golang/v2/okta"
)

func TestAccAppSamlAppSettings_crud(t *testing.T) {
ri := acctest.RandInt()
mgr := newFixtureManager(appSamlAppSettings)
preconfigured := mgr.GetFixtures("preconfigured.tf", ri, t)
updated := mgr.GetFixtures("preconfigured_updated.tf", ri, t)
resourceName := fmt.Sprintf("%s.test", appSamlAppSettings)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProvidersFactories,
CheckDestroy: createCheckResourceDestroy(appSaml, createDoesAppExist(okta.NewSamlApplication())),
Steps: []resource.TestStep{
{
Config: preconfigured,
Check: resource.ComposeTestCheckFunc(
checkAppSamlAppSettingsExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "settings", "{\"appFilter\":\"okta\",\"awsEnvironmentType\":\"aws.amazon\",\"groupFilter\":\"aws_(?{{accountid}}\\\\\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\\\\\-_]+)\",\"joinAllRoles\":false,\"loginURL\":\"https://console.aws.amazon.com/ec2/home\",\"roleValuePattern\":\"arn:aws:iam::${accountid}:saml-provider/OKTA,arn:aws:iam::${accountid}:role/${role}\",\"sessionDuration\":7600,\"useGroupMapping\":false}"),
),
},
{
Config: updated,
Check: resource.ComposeTestCheckFunc(
checkAppSamlAppSettingsExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "settings", "{\"appFilter\":\"okta\",\"awsEnvironmentType\":\"aws.amazon\",\"groupFilter\":\"aws_(?{{accountid}}\\\\\\\\d+)_(?{{role}}[a-zA-Z0-9+=,.@\\\\\\\\-_]+)\",\"joinAllRoles\":false,\"loginURL\":\"https://console.aws.amazon.com/ec2/home\",\"roleValuePattern\":\"arn:aws:iam::${accountid}:saml-provider/OKTA,arn:aws:iam::${accountid}:role/${role}\",\"sessionDuration\":3200,\"useGroupMapping\":false}"),
),
},
},
})
}

func checkAppSamlAppSettingsExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
missingErr := fmt.Errorf("resource not found: %s", name)
rs, ok := s.RootModule().Resources[name]
if !ok {
return missingErr
}
appID := rs.Primary.Attributes["app_id"]
client := getOktaClientFromMetadata(testAccProvider.Meta())
app := okta.NewSamlApplication()
_, _, err := client.Application.GetApplication(context.Background(), appID, app, nil)
if err != nil {
return err
}
settings := make(okta.ApplicationSettingsApplication)
_ = json.Unmarshal([]byte(rs.Primary.Attributes["settings"]), &settings)
for k, v := range *app.Settings.App {
if v == nil {
delete(*app.Settings.App, k)
}
}
e := reflect.DeepEqual(*app.Settings.App, settings)
if !e {
return fmt.Errorf("settings are not equal: actual: %+v , expected: %+v", *app.Settings.App, settings)
}
return nil
}
}
15 changes: 15 additions & 0 deletions okta/resource_okta_behavior_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/okta/okta-sdk-golang/v2/okta/query"
)

func sweepBehaviors(client *testClient) error {
var errorList []error
behaviors, _, err := client.apiSupplement.ListBehaviors(context.Background(), &query.Params{Q: testResourcePrefix})
if err != nil {
return err
}
for _, b := range behaviors {
if _, err := client.apiSupplement.DeleteBehavior(context.Background(), b.ID); err != nil {
errorList = append(errorList, err)
}
}
return condenseError(errorList)
}

func TestAccOktaBehavior(t *testing.T) {
ri := acctest.RandInt()
mgr := newFixtureManager(behavior)
Expand Down
2 changes: 1 addition & 1 deletion okta/resource_okta_group_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
func sweepGroupRules(client *testClient) error {
var errorList []error
// Should never need to deal with pagination
rules, _, err := client.oktaClient.Group.ListGroupRules(context.Background(), &query.Params{Limit: 300})
rules, _, err := client.oktaClient.Group.ListGroupRules(context.Background(), &query.Params{Limit: defaultPaginationLimit})
if err != nil {
return err
}
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_auto_login.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_auto_login

Creates an Auto Login Okta Application.

This resource allows you to create and configure an Auto Login Okta Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_basic_auth.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_basic_auth

Creates a Basic Auth Application.

This resource allows you to create and configure a Basic Auth Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_bookmark.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_bookmark

Creates a Bookmark Application.

This resource allows you to create and configure a Bookmark Application.

## Example Usage
Expand Down
2 changes: 0 additions & 2 deletions website/docs/r/app_oauth.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ description: |-

# okta_app_oauth

Creates an OIDC Application.

This resource allows you to create and configure an OIDC Application.

## Example Usage
Expand Down
6 changes: 2 additions & 4 deletions website/docs/r/app_saml.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ layout: 'okta'
page_title: 'Okta: okta_app_saml'
sidebar_current: 'docs-okta-resource-app-saml'
description: |-
Creates an SAML Application.
Creates a SAML Application.
---

# okta_app_saml

Creates an SAML Application.

This resource allows you to create and configure an SAML Application.
This resource allows you to create and configure a SAML Application.

## Example Usage

Expand Down
Loading