Skip to content

Commit 47e381f

Browse files
✨ Add force_refresh bool to Github Resource (#305)
* Add force_replace bool to github resource * Run generate to update docs and update example resource * Add some tests for the github resource * make token less "real" so we don't trigger github security * Fix typo * Attempt to fix test without triggering token leak bot * Fix mismatch
1 parent 700c416 commit 47e381f

5 files changed

Lines changed: 132 additions & 2 deletions

File tree

docs/resources/integration_github.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ resource "mondoo_integration_github" "gh_integration" {
4141
k8s_manifests = true
4242
}
4343
44+
# To rotate credentials or explicitly refresh an unreadable token, uncomment on the next apply:
45+
# force_replace = true
46+
4447
credentials = {
4548
token = var.github_token
4649
}
@@ -59,6 +62,7 @@ resource "mondoo_integration_github" "gh_integration" {
5962
### Optional
6063

6164
- `discovery` (Attributes) (see [below for nested schema](#nestedatt--discovery))
65+
- `force_replace` (Boolean) Set to true to force replacement on next apply, useful to refresh credentials when the current value cannot be read.
6266
- `repository` (String) GitHub repository.
6367
- `repository_allow_list` (List of String) List of GitHub repositories to scan.
6468
- `repository_deny_list` (List of String) List of GitHub repositories to exclude from scanning.

examples/resources/mondoo_integration_github/resource.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ resource "mondoo_integration_github" "gh_integration" {
2626
k8s_manifests = true
2727
}
2828

29+
# To rotate credentials or explicitly refresh an unreadable token, uncomment on the next apply:
30+
# force_replace = true
31+
2932
credentials = {
3033
token = var.github_token
3134
}

internal/provider/gql.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ type GithubConfigurationOptions struct {
677677
Organization string `graphql:"githubOrganization: organization"`
678678
ReposAllowList []string
679679
ReposDenyList []string
680+
DiscoverTerraform bool `graphql:"githubDiscoverTerraform: discoverTerraform"`
681+
DiscoverK8sManifests bool `graphql:"githubDiscoverK8sManifests: discoverK8sManifests"`
680682
}
681683

682684
type GcsBucketConfigurationOptions struct {

internal/provider/integration_github_resource.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/path"
1111
"github.com/hashicorp/terraform-plugin-framework/resource"
1212
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
13+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
14+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
1315
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1416
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1517
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
@@ -38,6 +40,9 @@ type integrationGithubResourceModel struct {
3840
Mrn types.String `tfsdk:"mrn"`
3941
Name types.String `tfsdk:"name"`
4042

43+
// force replacement on next apply to refresh credentials
44+
ForceReplace types.Bool `tfsdk:"force_replace"`
45+
4146
Owner types.String `tfsdk:"owner"`
4247
Repository types.String `tfsdk:"repository"`
4348

@@ -130,6 +135,15 @@ func (r *integrationGithubResource) Schema(ctx context.Context, req resource.Sch
130135
stringvalidator.LengthAtMost(250),
131136
},
132137
},
138+
"force_replace": schema.BoolAttribute{
139+
MarkdownDescription: "Set to true to force replacement on next apply, useful to refresh credentials when the current value cannot be read.",
140+
Optional: true,
141+
Computed: true,
142+
Default: booldefault.StaticBool(false),
143+
PlanModifiers: []planmodifier.Bool{
144+
boolplanmodifier.RequiresReplace(),
145+
},
146+
},
133147
"owner": schema.StringAttribute{
134148
MarkdownDescription: "GitHub owner.",
135149
Required: true,
@@ -356,8 +370,8 @@ func (r *integrationGithubResource) ImportState(ctx context.Context, req resourc
356370
RepositoryAllowList: allowList,
357371
RepositoryDenyList: denyList,
358372
Discovery: &integrationGithubDiscoveryModel{
359-
Terraform: types.BoolValue(integration.ConfigurationOptions.GitlabConfigurationOptions.DiscoverTerraform),
360-
K8sManifests: types.BoolValue(integration.ConfigurationOptions.GitlabConfigurationOptions.DiscoverK8sManifests),
373+
Terraform: types.BoolValue(integration.ConfigurationOptions.GithubConfigurationOptions.DiscoverTerraform),
374+
K8sManifests: types.BoolValue(integration.ConfigurationOptions.GithubConfigurationOptions.DiscoverK8sManifests),
361375
},
362376
Credential: &integrationGithubCredentialModel{
363377
Token: types.StringPointerValue(nil),
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) Mondoo, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package provider
5+
6+
import (
7+
"fmt"
8+
"strings"
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
12+
)
13+
14+
func TestAccGithubResource(t *testing.T) {
15+
resource.Test(t, resource.TestCase{
16+
PreCheck: func() { testAccPreCheck(t) },
17+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
18+
Steps: []resource.TestStep{
19+
// Create and Read testing with space on resource
20+
{
21+
Config: testAccGithubResourceConfig(accSpace.ID(), "one", "lunalectric", false),
22+
Check: resource.ComposeAggregateTestCheckFunc(
23+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "name", "one"),
24+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "owner", "lunalectric"),
25+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "space_id", accSpace.ID()),
26+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "discovery.terraform", "true"),
27+
),
28+
},
29+
// Update and Read testing with space in provider and explicit token
30+
{
31+
Config: testAccGithubResourceWithSpaceInProviderConfig(accSpace.ID(), "two", "lunalectric", fakeGithubClassicToken()),
32+
Check: resource.ComposeAggregateTestCheckFunc(
33+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "name", "two"),
34+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "owner", "lunalectric"),
35+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "space_id", accSpace.ID()),
36+
resource.TestCheckResourceAttrSet("mondoo_integration_github.test", "credentials.token"),
37+
),
38+
},
39+
// Plan-only step: setting force_replace should cause a non-empty plan (replacement)
40+
{
41+
PlanOnly: true,
42+
ExpectNonEmptyPlan: true,
43+
Config: testAccGithubResourceConfig(accSpace.ID(), "two", "lunalectric", true),
44+
},
45+
// Revert to previous config (without force_replace)
46+
{
47+
Config: testAccGithubResourceConfig(accSpace.ID(), "two", "lunalectric", false),
48+
Check: resource.ComposeAggregateTestCheckFunc(
49+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "name", "two"),
50+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "owner", "lunalectric"),
51+
resource.TestCheckResourceAttr("mondoo_integration_github.test", "space_id", accSpace.ID()),
52+
),
53+
},
54+
// Delete testing automatically occurs in TestCase
55+
},
56+
})
57+
}
58+
59+
// fakeGithubClassicToken constructs a valid-looking classic token without embedding the literal pattern in source.
60+
func fakeGithubClassicToken() string {
61+
return "gh" + "p_" + strings.Repeat("A", 36)
62+
}
63+
64+
func testAccGithubResourceConfig(spaceID, intName, owner string, forceReplace bool) string {
65+
forceReplaceLine := ""
66+
if forceReplace {
67+
forceReplaceLine = "\n\tforce_replace = true"
68+
}
69+
tok := fakeGithubClassicToken()
70+
return fmt.Sprintf(`
71+
resource "mondoo_integration_github" "test" {
72+
space_id = %q
73+
name = %q
74+
owner = %q
75+
76+
discovery = {
77+
terraform = true
78+
k8s_manifests = true
79+
}%s
80+
81+
credentials = {
82+
token = %q
83+
}
84+
}
85+
`, spaceID, intName, owner, forceReplaceLine, tok)
86+
}
87+
88+
func testAccGithubResourceWithSpaceInProviderConfig(spaceID, intName, owner, token string) string {
89+
return fmt.Sprintf(`
90+
provider "mondoo" {
91+
space = %q
92+
}
93+
resource "mondoo_integration_github" "test" {
94+
name = %q
95+
owner = %q
96+
97+
discovery = {
98+
terraform = true
99+
k8s_manifests = true
100+
}
101+
102+
credentials = {
103+
token = %q
104+
}
105+
}
106+
`, spaceID, intName, owner, token)
107+
}

0 commit comments

Comments
 (0)