Skip to content

Commit

Permalink
fix: requested changes
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Theuermann <[email protected]>
  • Loading branch information
mati007thm committed Dec 9, 2024
1 parent 52d0c9a commit 7d02977
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 56 deletions.
26 changes: 18 additions & 8 deletions internal/provider/gql.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,15 +609,25 @@ type ShodanConfigurationOptions struct {
Targets []string
}

type MicrosoftDefenderConfigurationOptionsInput struct {
TenantId string
ClientId string
SubscriptionsAllowlist []string
SubscriptionsDenylist []string
Certificate string
ClientSecret string
}

type ClientIntegrationConfigurationOptions struct {
AzureConfigurationOptions AzureConfigurationOptions `graphql:"... on AzureConfigurationOptions"`
HostConfigurationOptions HostConfigurationOptions `graphql:"... on HostConfigurationOptions"`
Ms365ConfigurationOptions Ms365ConfigurationOptions `graphql:"... on Ms365ConfigurationOptions"`
GcpConfigurationOptions GcpConfigurationOptions `graphql:"... on GcpConfigurationOptions"`
SlackConfigurationOptions SlackConfigurationOptions `graphql:"... on SlackConfigurationOptions"`
GithubConfigurationOptions GithubConfigurationOptions `graphql:"... on GithubConfigurationOptions"`
HostedAwsConfigurationOptions HostedAwsConfigurationOptions `graphql:"... on HostedAwsConfigurationOptions"`
ShodanConfigurationOptions ShodanConfigurationOptions `graphql:"... on ShodanConfigurationOptions"`
AzureConfigurationOptions AzureConfigurationOptions `graphql:"... on AzureConfigurationOptions"`
HostConfigurationOptions HostConfigurationOptions `graphql:"... on HostConfigurationOptions"`
Ms365ConfigurationOptions Ms365ConfigurationOptions `graphql:"... on Ms365ConfigurationOptions"`
GcpConfigurationOptions GcpConfigurationOptions `graphql:"... on GcpConfigurationOptions"`
SlackConfigurationOptions SlackConfigurationOptions `graphql:"... on SlackConfigurationOptions"`
GithubConfigurationOptions GithubConfigurationOptions `graphql:"... on GithubConfigurationOptions"`
HostedAwsConfigurationOptions HostedAwsConfigurationOptions `graphql:"... on HostedAwsConfigurationOptions"`
ShodanConfigurationOptions ShodanConfigurationOptions `graphql:"... on ShodanConfigurationOptions"`
MicrosoftDefenderConfigurationOptionsInput MicrosoftDefenderConfigurationOptionsInput `graphql:"... on MicrosoftDefenderConfigurationOptionsInput"`
// Add other configuration options here
}

Expand Down
97 changes: 49 additions & 48 deletions internal/provider/integration_msdefender_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ type integrationMsDefenderCredentialModel struct {
PEMFile types.String `tfsdk:"pem_file"`
}

func (m integrationMsDefenderResourceModel) GetConfigurationOptions() *mondoov1.MicrosoftDefenderConfigurationOptionsInput {
opts := &mondoov1.MicrosoftDefenderConfigurationOptionsInput{
TenantID: mondoov1.String(m.TenantId.ValueString()),
ClientID: mondoov1.String(m.ClientId.ValueString()),
Certificate: mondoov1.NewStringPtr(mondoov1.String(m.Credential.PEMFile.ValueString())),
}

ctx := context.Background()
var listAllow []mondoov1.String
allowlist, _ := m.SubscriptionAllowList.ToListValue(ctx)
allowlist.ElementsAs(ctx, &listAllow, true)

var listDeny []mondoov1.String
denylist, _ := m.SubscriptionDenyList.ToListValue(ctx)
denylist.ElementsAs(ctx, &listDeny, true)

opts.SubscriptionsAllowlist = &listAllow
opts.SubscriptionsDenylist = &listDeny

return opts
}

func (r *integrationMsDefenderResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_integration_msdefender"
}
Expand Down Expand Up @@ -159,36 +181,13 @@ func (r *integrationMsDefenderResource) Create(ctx context.Context, req resource
ctx = tflog.SetField(ctx, "space_mrn", space.MRN())

// Do GraphQL request to API to create the resource.
var listAllow []mondoov1.String
allowlist, _ := data.SubscriptionAllowList.ToListValue(ctx)
allowlist.ElementsAs(ctx, &listAllow, true)

var listDeny []mondoov1.String
denylist, _ := data.SubscriptionDenyList.ToListValue(ctx)
denylist.ElementsAs(ctx, &listDeny, true)

// Check if both whitelist and blacklist are provided
if len(listDeny) > 0 && len(listAllow) > 0 {
resp.Diagnostics.
AddError("ConflictingAttributesError",
"Both subscription_allow_list and subscription_deny_list cannot be provided simultaneously.",
)
return
}

tflog.Debug(ctx, "Creating integration")
integration, err := r.client.CreateIntegration(ctx,
space.MRN(),
data.Name.ValueString(),
mondoov1.ClientIntegrationTypeMicrosoftDefender,
mondoov1.ClientIntegrationConfigurationInput{
MicrosoftDefenderConfigurationOptions: &mondoov1.MicrosoftDefenderConfigurationOptionsInput{
TenantID: mondoov1.String(data.TenantId.ValueString()),
ClientID: mondoov1.String(data.ClientId.ValueString()),
SubscriptionsAllowlist: &listAllow,
SubscriptionsDenylist: &listDeny,
Certificate: mondoov1.NewStringPtr(mondoov1.String(data.Credential.PEMFile.ValueString())),
},
MicrosoftDefenderConfigurationOptions: data.GetConfigurationOptions(),
})
if err != nil {
resp.Diagnostics.
Expand Down Expand Up @@ -245,31 +244,8 @@ func (r *integrationMsDefenderResource) Update(ctx context.Context, req resource
}

// Do GraphQL request to API to update the resource.
var listAllow []mondoov1.String
allowlist, _ := data.SubscriptionAllowList.ToListValue(ctx)
allowlist.ElementsAs(ctx, &listAllow, true)

var listDeny []mondoov1.String
denylist, _ := data.SubscriptionDenyList.ToListValue(ctx)
denylist.ElementsAs(ctx, &listDeny, true)

// Check if both whitelist and blacklist are provided
if len(listDeny) > 0 && len(listAllow) > 0 {
resp.Diagnostics.
AddError("ConflictingAttributesError",
"Both subscription_allow_list and subscription_deny_list cannot be provided simultaneously.",
)
return
}

opts := mondoov1.ClientIntegrationConfigurationInput{
MicrosoftDefenderConfigurationOptions: &mondoov1.MicrosoftDefenderConfigurationOptionsInput{
TenantID: mondoov1.String(data.TenantId.ValueString()),
ClientID: mondoov1.String(data.ClientId.ValueString()),
SubscriptionsAllowlist: &listAllow,
SubscriptionsDenylist: &listDeny,
Certificate: mondoov1.NewStringPtr(mondoov1.String(data.Credential.PEMFile.ValueString())),
},
MicrosoftDefenderConfigurationOptions: data.GetConfigurationOptions(),
}

_, err := r.client.UpdateIntegration(ctx,
Expand Down Expand Up @@ -310,3 +286,28 @@ func (r *integrationMsDefenderResource) Delete(ctx context.Context, req resource
return
}
}

func (r *integrationMsDefenderResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
integration, ok := r.client.ImportIntegration(ctx, req, resp)
if !ok {
return
}

allowList := ConvertListValue(integration.ConfigurationOptions.MicrosoftDefenderConfigurationOptionsInput.SubscriptionsAllowlist)
denyList := ConvertListValue(integration.ConfigurationOptions.MicrosoftDefenderConfigurationOptionsInput.SubscriptionsDenylist)

model := integrationMsDefenderResourceModel{
Mrn: types.StringValue(integration.Mrn),
Name: types.StringValue(integration.Name),
SpaceID: types.StringValue(integration.SpaceID()),
ClientId: types.StringValue(integration.ConfigurationOptions.MicrosoftDefenderConfigurationOptionsInput.ClientId),
TenantId: types.StringValue(integration.ConfigurationOptions.MicrosoftDefenderConfigurationOptionsInput.TenantId),
SubscriptionAllowList: allowList,
SubscriptionDenyList: denyList,
Credential: integrationMsDefenderCredentialModel{
PEMFile: types.StringValue(integration.ConfigurationOptions.MicrosoftDefenderConfigurationOptionsInput.Certificate),
},
}

resp.State.Set(ctx, &model)
}
93 changes: 93 additions & 0 deletions internal/provider/integration_msdefender_resource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package provider

import (
"fmt"
"testing"

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

func TestAccMsDefenderIntegrationResource(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccMsDefenderIntegrationResourceConfig(accSpace.ID(), "one", "ffffffff-ffff-ffff-ffff-ffffffffffff", "ffffffff-ffff-ffff-ffff-ffffffffffff", []string{"ffffffff-ffff-ffff-ffff-ffffffffffff", "ffffffff-ffff-ffff-ffff-ffffffffffff"}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "name", "one"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "space_id", accSpace.ID()),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "tenant_id", "ffffffff-ffff-ffff-ffff-ffffffffffff"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "client_id", "ffffffff-ffff-ffff-ffff-ffffffffffff"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "subscription_allow_list.#", "2"),
),
},
{
Config: testAccMsDefenderIntegrationResourceWithSpaceInProviderConfig(accSpace.ID(), "two", "abcd1234567890", []string{"ffffffff-ffff-ffff-ffff-ffffffffffff", "ffffffff-ffff-ffff-ffff-ffffffffffff"}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "name", "two"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "space_id", accSpace.ID()),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "subscription_deny_list.#", "2"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "credentials.0.pem_file", "abcd1234567890"),
),
},
// Update and Read testing
{
Config: testAccMsDefenderIntegrationResourceConfig(accSpace.ID(), "three", "ffffffff-ffff-ffff-ffff-ffffffffff", "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", []string{"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "name", "three"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "space_id", accSpace.ID()),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "tenant_id", "ffffffff-ffff-ffff-ffff-ffffffffff"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "client_id", "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "subscription_allow_list.#", "2"),
),
},
{
Config: testAccMsDefenderIntegrationResourceWithSpaceInProviderConfig(accSpace.ID(), "four", "abcd1234567890", []string{"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "name", "four"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "space_id", accSpace.ID()),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "subscription_deny_list.#", "2"),
resource.TestCheckResourceAttr("mondoo_integration_msdefender.msdefender_integration", "credentials.0.pem_file", "abcd1234567890"),
),
},
// Delete testing automatically occurs in TestCase
},
})
}

func testAccMsDefenderIntegrationResourceConfig(spaceID, intName, tenantID, clientID string, allowList []string) string {
return fmt.Sprintf(`
resource "mondoo_integration_msdefender" "msdefender_integration" {
space_id = %[1]q
name = %[2]q
tenant_id = %[3]q
client_id = %[4]q
subscription_allow_list= %[5]q
credentials = {
pem_file = "abcd1234567890"
}
}
`, spaceID, intName, tenantID, clientID, allowList)
}

func testAccMsDefenderIntegrationResourceWithSpaceInProviderConfig(spaceID, intName, pemFile string, denyList []string) string {
return fmt.Sprintf(`
provider "mondoo" {
space = %[1]q
}
resource "mondoo_integration_msdefender" "msdefender_integration" {
name = %[2]q
tenant_id = "ffffffff-ffff-ffff-ffff-ffffffffffff"
client_id = "ffffffff-ffff-ffff-ffff-ffffffffffff"
subscription_deny_list = %[3]q
credentials = {
pem_file = %[4]q
}
}
`, spaceID, intName, denyList, pemFile)
}

0 comments on commit 7d02977

Please sign in to comment.