Skip to content

Commit

Permalink
- add some more simple tests
Browse files Browse the repository at this point in the history
- start to add SDK->Model code
  • Loading branch information
jamesatwill-okta committed Nov 18, 2024
1 parent a2f0ec6 commit 79b0b2e
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 34 deletions.
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.22.0
toolchain go1.23.2

require (
github.com/atko-pam/pam-sdk-go v1.1.0
github.com/atko-pam/pam-sdk-go v1.1.1
github.com/go-resty/resty/v2 v2.7.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
Expand Down
15 changes: 14 additions & 1 deletion oktapam/convert/security_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,26 @@ func SecurityPolicyFromSDKToModel(ctx context.Context, in *pam.SecurityPolicy, o
out.Type = types.StringValue(string(*in.Type))
}

out.Description = types.StringPointerValue(in.Description)
if in.Description != nil {
out.Description = types.StringPointerValue(in.Description)
}

out.Active = types.BoolValue(in.Active)

if diags := SecurityPolicyPrincipalFromSDKToModel(ctx, &in.Principals, &out.Principals); diags.HasError() {
return diags
}

if len(in.Rules) > 0 {
var outRules []SecurityPolicyRuleModel
for _, rule := range in.Rules {
var outRule SecurityPolicyRuleModel
if diags := SecurityPolicyRuleFromSDKToModel(ctx, &rule, &outRule); diags.HasError() {
return diags
}
outRules = append(outRules, outRule)
}
}
//TODO(ja) - Rules
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package convert

import (
"context"

"github.com/atko-pam/pam-sdk-go/client/pam"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -25,6 +27,12 @@ func SecurityPolicyPasswordCheckoutDatabasePrivilegeSchema() schema.Attribute {
}
}

func SecurityPolicyPasswordCheckoutDatabasePrivilegeAttrTypes() map[string]attr.Type {
return map[string]attr.Type{
"password_checkout_database": types.BoolType,
}
}

func SecurityPolicyPasswordCheckoutDatabasePrivilegeFromModelToSDK(_ context.Context, in *SecurityPolicyPasswordCheckoutDatabasePrivilegeModel, out *pam.SecurityPolicyPasswordCheckoutDatabasePrivilege) diag.Diagnostics {
out.Type = pam.SecurityPolicyRulePrivilegeType_PASSWORD_CHECKOUT_DATABASE
out.PasswordCheckoutDatabase = in.PasswordCheckoutDatabase.ValueBool()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package convert

import (
"context"

"github.com/atko-pam/pam-sdk-go/client/pam"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -25,6 +27,12 @@ func SecurityPolicyPasswordCheckoutSSHPrivilegeSchema() schema.Attribute {
}
}

func SecurityPolicyPasswordCheckoutSSHPrivilegeAttrTypes() map[string]attr.Type {
return map[string]attr.Type{
"password_checkout_ssh": types.BoolType,
}
}

func SecurityPolicyPasswordCheckoutSSHPrivilegeFromModelToSDK(_ context.Context, in *SecurityPolicyPasswordCheckoutSSHPrivilegeModel, out *pam.SecurityPolicyPasswordCheckoutSSHPrivilege) diag.Diagnostics {
out.Type = pam.SecurityPolicyRulePrivilegeType_PASSWORD_CHECKOUT_SSH
out.PasswordCheckoutSsh = in.PasswordCheckoutSSH.ValueBool()
Expand Down
11 changes: 11 additions & 0 deletions oktapam/convert/security_policy_principal_account_ssh_privilege.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package convert

import (
"context"

"github.com/atko-pam/pam-sdk-go/client/pam"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -59,3 +61,12 @@ func SecurityPolicyPrincipalAccountSSHPrivilegeSchema() schema.Attribute {
Optional: true,
}
}

func SecurityPolicyPrincipalAccountSSHPrivilegeAttrTypes() map[string]attr.Type {
return map[string]attr.Type{
"principal_account_ssh": types.BoolType,
"admin_level_permissions": types.BoolType,
"sudo_display_name": types.StringType,
"sudo_command_bundles": types.ListType{ElemType: types.StringType},
}
}
1 change: 1 addition & 0 deletions oktapam/convert/security_policy_principals.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package convert

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/attr"

"github.com/atko-pam/pam-sdk-go/client/pam"
Expand Down
11 changes: 11 additions & 0 deletions oktapam/convert/security_policy_privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package convert

import (
"context"

"github.com/atko-pam/pam-sdk-go/client/pam"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

//type SecurityPolicyRulePrivilegeTypeModel types.String
Expand Down Expand Up @@ -38,6 +41,14 @@ func SecurityPolicyRulePrivilegeContainerSchema() schema.NestedAttributeObject {
}
}

func SecurityPolicyRulePrivilegeContainerAttrTypes() map[string]attr.Type {
return map[string]attr.Type{
"password_checkout_database": types.ObjectType{AttrTypes: SecurityPolicyPasswordCheckoutDatabasePrivilegeAttrTypes()},
"principal_account_ssh": types.ObjectType{AttrTypes: SecurityPolicyPrincipalAccountSSHPrivilegeAttrTypes()},
"password_checkout_ssh": types.ObjectType{AttrTypes: SecurityPolicyPasswordCheckoutSSHPrivilegeAttrTypes()},
}
}

func SecurityPolicyRulePrivilegeContainerFromSDKToModel(ctx context.Context, in *pam.SecurityPolicyRulePrivilegeContainer, out *SecurityPolicyRulePrivilegeContainerModel) diag.Diagnostics {
if in.PrivilegeValue.SecurityPolicyPasswordCheckoutDatabasePrivilege != nil {
if diags := SecurityPolicyPasswordCheckoutDatabasePrivilegeFromSDKToModel(ctx, in.PrivilegeValue.SecurityPolicyPasswordCheckoutDatabasePrivilege, out.SecurityPolicyPasswordCheckoutDatabasePrivilege); diags.HasError() {
Expand Down
10 changes: 5 additions & 5 deletions oktapam/convert/security_policy_resource_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,15 @@ func SelectorIndividualServerFromModelToSDK(_ context.Context, in *SelectorIndiv
}

type SelectorIndividualServerAccountModel struct {
ServerId types.String/*NamedObject*/ `tfsdk:"server_id"`
Server types.String/*NamedObject*/ `tfsdk:"server"`
Username types.String `tfsdk:"username"`
}

func SelectorIndividualServerAccountSchema() schema.Attribute {
return schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"server_id": schema.StringAttribute{Required: true},
"username": schema.StringAttribute{Required: true},
"server": schema.StringAttribute{Required: true},
"username": schema.StringAttribute{Required: true},
},
Optional: true,
}
Expand All @@ -182,8 +182,8 @@ func SelectorIndividualServerAccountSchema() schema.Attribute {
func SelectorIndividualServerAccountFromModelToSDK(_ context.Context, in *SelectorIndividualServerAccountModel, out *pam.SelectorIndividualServerAccount) diag.Diagnostics {
out.Type = string(pam.SecurityPolicyRuleServerBasedResourceSubSelectorType_INDIVIDUAL_SERVER_ACCOUNT) //TODO(ja) this should probably be hard coded
out.Username = in.Username.ValueStringPointer()
if !in.ServerId.IsNull() {
out.Server = *pam.NewNamedObject().SetId(in.ServerId.ValueString())
if !in.Server.IsNull() && !in.Server.IsUnknown() {
out.Server = *pam.NewNamedObject().SetId(in.Server.ValueString())
}
out.Username = in.Username.ValueStringPointer()
return nil
Expand Down
8 changes: 8 additions & 0 deletions oktapam/convert/security_policy_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,21 @@ func SecurityPolicyRuleFromModelToSDK(ctx context.Context, in *SecurityPolicyRul
}

func SecurityPolicyRuleFromSDKToModel(ctx context.Context, in *pam.SecurityPolicyRule, out *SecurityPolicyRuleModel) diag.Diagnostics {

if securityPolicyID, ok := in.GetSecurityPolicyIdOk(); ok {
out.SecurityPolicyID = types.StringPointerValue(securityPolicyID)
}
out.Name = types.StringValue(in.Name)
out.ResourceType = types.StringValue(string(in.ResourceType))

if diags := SecurityPolicyRuleResourceSelectorFromSDKToModel(ctx, &in.ResourceSelector, &out.ResourceSelector); diags.HasError() {
return diags
}

// TODO(ja) Privileges

out.OverrideCheckoutDurationInSeconds = types.Int64PointerValue(in.OverrideCheckoutDurationInSeconds.Get())

// TODO(ja) Conditions
return nil
}
131 changes: 104 additions & 27 deletions oktapam/resource_security_policy2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,72 @@ import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"testing"

"github.com/atko-pam/pam-sdk-go/client/pam"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/require"
"io"
"net/http"
"regexp"
"testing"
)

const individualServerAccountSelectorPolicyTerraform = `resource "oktapam_security_policy_v2" "individual_server_account_policy" {
name = "test individual server account selector"
active = true
principals = { user_groups = ["user_group_1", "user_group_2"] }
rules = [
{
name = "test"
resource_type = "server_based_resource"
resource_selector = {
server_based_resource = {
selectors = [
{
individual_server_account = {
server = "server-id-goes-here"
username = "root"
}
}
]
}
}
privileges = [{ password_checkout_ssh = { password_checkout_ssh = true } }]
}
]
}
`

const individualServerSelectorPolicyTerraform = `resource "oktapam_security_policy_v2" "individual_server_policy" {
name = "test individual server selector"
active = true
principals = { user_groups = ["user_group_1", "user_group_2"] }
rules = [
{
name = "test"
resource_type = "server_based_resource"
resource_selector = {
server_based_resource = {
selectors = [
{ individual_server = { server = "server-id-goes-here" } }
]
}
}
privileges = [{ password_checkout_ssh = { password_checkout_ssh = true } }]
}
]
}
`

// language=Terraform
const securityPolicyTerraform = `resource "oktapam_security_policy_v2" "tilt_security_policy" {
const devEnvSecurityPolicyTerraform = `resource "oktapam_security_policy_v2" "devenv_security_policy" {
type = "default"
name = "tilt-security-policy"
description = "An example security policy for Tilt"
name = "development environment policy"
description = "An example security policy for dev environment"
active = true
principals = {
user_groups = ["user_group_id_1", "user_group_id_2"]
Expand Down Expand Up @@ -140,23 +190,6 @@ const securityPolicyTerraform = `resource "oktapam_security_policy_v2" "tilt_sec
}
`

const securityPolicyJSON = `
{
"active" : true,
"description" : "",
"id" : "",
"name" : "tilt-security-policy",
"principals" : {
"user_groups" : [ {
"name" : "user_group_id_1"
}, {
"name" : "user_group_id_2"
} ]
},
"rules" : null
}
`

const sudoCommandBundlesTerraform = `# Create a sudo command bundle
resource "oktapam_sudo_command_bundle" "tilt_sudo_create_directories" {
name = "create_directories"
Expand All @@ -179,7 +212,7 @@ resource "oktapam_sudo_command_bundle" "tilt_sudo_remove_directories" {
}
`

const terraformConfig = sudoCommandBundlesTerraform + "\n" + securityPolicyTerraform
const devEnvTerraformConfig = sudoCommandBundlesTerraform + "\n" + devEnvSecurityPolicyTerraform

func entityId(body []byte) string {
sum := sha256.Sum256(body)
Expand Down Expand Up @@ -234,15 +267,59 @@ func setupHTTPMock(t *testing.T) {
)
}

func TestSimple(t *testing.T) {
// Loopback tests are designed to convert a Terraform resource into the SDK representation, marshal it, pretend
// to call an HTTP call which will unmarshal it, assign it an ID, then marshal a response and send that back. The
// Terraform provider will in turn unmarshal from JSON to SDK, then convert from SDK to Terraform model. At its
// root, loopback tests are Garbage In/Garbage Out. For example, if you don't take a resource field and set it in
// the SDK, _and_ you're not converting it from the SDK back to the Terraform resource, then nobody will notice. You
// can improve that by including a canonical expectation of what the JSON should look like and require.JSONEq checking.

// TestSecurityPolicyLoopback_DevEnv uses an example policy from our development environment.
func TestSecurityPolicyLoopback_DevEnv(t *testing.T) {

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: httpMockTestV6ProviderFactories(),
Steps: []resource.TestStep{
{
PreConfig: func() { setupHTTPMock(t) },
Config: devEnvTerraformConfig,
Check: func(s *terraform.State) error {
return nil
},
},
},
})
}

// TestSecurityPolicyLoopback_IndividualServer does a test on a resource with an "individual server" resource
// selector.
func TestSecurityPolicyLoopback_IndividualServer(t *testing.T) {
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: httpMockTestV6ProviderFactories(),
Steps: []resource.TestStep{
{
PreConfig: func() { setupHTTPMock(t) },
Config: individualServerSelectorPolicyTerraform,
Check: func(s *terraform.State) error {
return nil
},
},
},
})
}

// TestSecurityPolicyLoopback_IndividualServerAccount does a loopback test on a resource with an "individual server
// account" resource selector.
func TestSecurityPolicyLoopback_IndividualServerAccount(t *testing.T) {
resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: httpMockTestV6ProviderFactories(),
Steps: []resource.TestStep{
{
PreConfig: func() { setupHTTPMock(t) },
Config: terraformConfig,
Config: individualServerAccountSelectorPolicyTerraform,
Check: func(s *terraform.State) error {
return nil
},
Expand Down

0 comments on commit 79b0b2e

Please sign in to comment.