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 encrypted_value to Actions + Organizations's secrets #807

Merged
merged 4 commits into from
Jun 8, 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
33 changes: 25 additions & 8 deletions github/resource_github_actions_organization_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/google/go-github/v35/github"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func resourceGithubActionsOrganizationSecret() *schema.Resource {
Expand All @@ -31,11 +32,20 @@ func resourceGithubActionsOrganizationSecret() *schema.Resource {
ForceNew: true,
ValidateFunc: validateSecretNameFunc,
},
"encrypted_value": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Sensitive: true,
ConflictsWith: []string{"plaintext_value"},
ValidateFunc: validation.StringIsBase64,
},
"plaintext_value": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Sensitive: true,
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Sensitive: true,
ConflictsWith: []string{"encrypted_value"},
},
"visibility": {
Type: schema.TypeString,
Expand Down Expand Up @@ -70,6 +80,7 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat

secretName := d.Get("secret_name").(string)
plaintextValue := d.Get("plaintext_value").(string)
var encryptedValue string

visibility := d.Get("visibility").(string)
selectedRepositories, hasSelectedRepositories := d.GetOk("selected_repository_ids")
Expand All @@ -95,9 +106,14 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat
return err
}

encryptedText, err := encryptPlaintext(plaintextValue, publicKey)
if err != nil {
return err
if encryptedText, ok := d.GetOk("encrypted_value"); ok {
encryptedValue = encryptedText.(string)
} else {
encryptedBytes, err := encryptPlaintext(plaintextValue, publicKey)
if err != nil {
return err
}
encryptedValue = base64.StdEncoding.EncodeToString(encryptedBytes)
}

// Create an EncryptedSecret and encrypt the plaintext value into it
Expand All @@ -106,7 +122,7 @@ func resourceGithubActionsOrganizationSecretCreateOrUpdate(d *schema.ResourceDat
KeyID: keyId,
Visibility: visibility,
SelectedRepositoryIDs: selectedRepositoryIDs,
EncryptedValue: base64.StdEncoding.EncodeToString(encryptedText),
EncryptedValue: encryptedValue,
}

_, err = client.Actions.CreateOrUpdateOrgSecret(ctx, owner, eSecret)
Expand Down Expand Up @@ -136,6 +152,7 @@ func resourceGithubActionsOrganizationSecretRead(d *schema.ResourceData, meta in
return err
}

d.Set("encrypted_value", d.Get("encrypted_value"))
d.Set("plaintext_value", d.Get("plaintext_value"))
d.Set("created_at", secret.CreatedAt.String())
d.Set("visibility", secret.Visibility)
Expand Down
50 changes: 33 additions & 17 deletions github/resource_github_actions_organization_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,50 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) {
updatedSecretValue := "updated_super_secret_value"

config := fmt.Sprintf(`
resource "github_actions_organization_secret" "test_secret" {
secret_name = "test_secret_name"
resource "github_actions_organization_secret" "plaintext_secret" {
secret_name = "test_plaintext_secret"
plaintext_value = "%s"
visibility = "private"
}
`, secretValue)

resource "github_actions_organization_secret" "encrypted_secret" {
secret_name = "test_encrypted_secret"
encrypted_value = "%s"
visibility = "private"
}
`, secretValue, secretValue)

checks := map[string]resource.TestCheckFunc{
"before": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_actions_organization_secret.test_secret", "plaintext_value",
"github_actions_organization_secret.plaintext_secret", "plaintext_value",
secretValue,
),
resource.TestCheckResourceAttr(
"github_actions_organization_secret.encrypted_secret", "encrypted_value",
secretValue,
),
resource.TestCheckResourceAttrSet(
"github_actions_organization_secret.test_secret", "created_at",
"github_actions_organization_secret.plaintext_secret", "created_at",
),
resource.TestCheckResourceAttrSet(
"github_actions_organization_secret.test_secret", "updated_at",
"github_actions_organization_secret.plaintext_secret", "updated_at",
),
),
"after": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_actions_organization_secret.test_secret", "plaintext_value",
"github_actions_organization_secret.plaintext_secret", "plaintext_value",
updatedSecretValue,
),
resource.TestCheckResourceAttr(
"github_actions_organization_secret.encrypted_secret", "encrypted_value",
updatedSecretValue,
),
resource.TestCheckResourceAttrSet(
"github_actions_organization_secret.test_secret", "created_at",
"github_actions_organization_secret.plaintext_secret", "created_at",
),
resource.TestCheckResourceAttrSet(
"github_actions_organization_secret.test_secret", "updated_at",
"github_actions_organization_secret.plaintext_secret", "updated_at",
),
),
}
Expand All @@ -60,7 +74,7 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) {
{
Config: strings.Replace(config,
secretValue,
updatedSecretValue, 1),
updatedSecretValue, 2),
Check: checks["after"],
},
},
Expand All @@ -81,15 +95,17 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) {
})

t.Run("deletes secrets without error", func(t *testing.T) {
secretValue := "super_secret_value"
config := `
resource "github_actions_organization_secret" "plaintext_secret" {
secret_name = "test_plaintext_secret"
visibility = "private"
}

config := fmt.Sprintf(`
resource "github_actions_organization_secret" "test_secret" {
secret_name = "test_secret_name"
plaintext_value = "%s"
resource "github_actions_organization_secret" "encrypted_secret" {
secret_name = "test_encrypted_secret"
visibility = "private"
}
`, secretValue)
`

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -122,7 +138,7 @@ func TestAccGithubActionsOrganizationSecret(t *testing.T) {

config := fmt.Sprintf(`
resource "github_actions_organization_secret" "test_secret" {
secret_name = "test_secret_name"
secret_name = "test_plaintext_secret"
plaintext_value = "%s"
visibility = "private"
}
Expand Down
30 changes: 23 additions & 7 deletions github/resource_github_actions_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,19 @@ func resourceGithubActionsSecret() *schema.Resource {
ForceNew: true,
ValidateFunc: validateSecretNameFunc,
},
"encrypted_value": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Sensitive: true,
ConflictsWith: []string{"plaintext_value"},
},
"plaintext_value": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Sensitive: true,
ConflictsWith: []string{"encrypted_value"},
},
"created_at": {
Type: schema.TypeString,
Expand All @@ -55,22 +64,28 @@ func resourceGithubActionsSecretCreateOrUpdate(d *schema.ResourceData, meta inte
repo := d.Get("repository").(string)
secretName := d.Get("secret_name").(string)
plaintextValue := d.Get("plaintext_value").(string)
var encryptedValue string

keyId, publicKey, err := getPublicKeyDetails(owner, repo, meta)
if err != nil {
return err
}

encryptedText, err := encryptPlaintext(plaintextValue, publicKey)
if err != nil {
return err
if encryptedText, ok := d.GetOk("encrypted_value"); ok {
encryptedValue = encryptedText.(string)
} else {
encryptedBytes, err := encryptPlaintext(plaintextValue, publicKey)
if err != nil {
return err
}
encryptedValue = base64.StdEncoding.EncodeToString(encryptedBytes)
}

// Create an EncryptedSecret and encrypt the plaintext value into it
eSecret := &github.EncryptedSecret{
Name: secretName,
KeyID: keyId,
EncryptedValue: base64.StdEncoding.EncodeToString(encryptedText),
EncryptedValue: encryptedValue,
}

_, err = client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, eSecret)
Expand Down Expand Up @@ -105,6 +120,7 @@ func resourceGithubActionsSecretRead(d *schema.ResourceData, meta interface{}) e
return err
}

d.Set("encrypted_value", d.Get("encrypted_value"))
d.Set("plaintext_value", d.Get("plaintext_value"))
d.Set("created_at", secret.CreatedAt.String())

Expand Down
53 changes: 33 additions & 20 deletions github/resource_github_actions_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,36 +74,50 @@ func TestAccGithubActionsSecret(t *testing.T) {
name = "tf-acc-test-%s"
}

resource "github_actions_secret" "test_secret" {
resource "github_actions_secret" "plaintext_secret" {
repository = github_repository.test.name
secret_name = "test_secret_name"
secret_name = "test_plaintext_secret"
plaintext_value = "%s"
}
`, randomID, secretValue)

resource "github_actions_secret" "encrypted_secret" {
repository = github_repository.test.name
secret_name = "test_encrypted_secret"
encrypted_value = "%s"
}
`, randomID, secretValue, secretValue)

checks := map[string]resource.TestCheckFunc{
"before": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_actions_secret.test_secret", "plaintext_value",
"github_actions_secret.plaintext_secret", "plaintext_value",
secretValue,
),
resource.TestCheckResourceAttr(
"github_actions_secret.encrypted_secret", "encrypted_value",
secretValue,
),
resource.TestCheckResourceAttrSet(
"github_actions_secret.test_secret", "created_at",
"github_actions_secret.plaintext_secret", "created_at",
),
resource.TestCheckResourceAttrSet(
"github_actions_secret.test_secret", "updated_at",
"github_actions_secret.plaintext_secret", "updated_at",
),
),
"after": resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"github_actions_secret.test_secret", "plaintext_value",
"github_actions_secret.plaintext_secret", "plaintext_value",
updatedSecretValue,
),
resource.TestCheckResourceAttr(
"github_actions_secret.encrypted_secret", "encrypted_value",
updatedSecretValue,
),
resource.TestCheckResourceAttrSet(
"github_actions_secret.test_secret", "created_at",
"github_actions_secret.plaintext_secret", "created_at",
),
resource.TestCheckResourceAttrSet(
"github_actions_secret.test_secret", "updated_at",
"github_actions_secret.plaintext_secret", "updated_at",
),
),
}
Expand All @@ -120,7 +134,7 @@ func TestAccGithubActionsSecret(t *testing.T) {
{
Config: strings.Replace(config,
secretValue,
updatedSecretValue, 1),
updatedSecretValue, 2),
Check: checks["after"],
},
},
Expand All @@ -138,24 +152,24 @@ func TestAccGithubActionsSecret(t *testing.T) {
t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})

})

t.Run("deletes secrets without error", func(t *testing.T) {

secretValue := "super_secret_value"

config := fmt.Sprintf(`
resource "github_repository" "test" {
name = "tf-acc-test-%s"
}

resource "github_actions_secret" "test_secret" {
repository = github_repository.test.name
secret_name = "test_secret_name"
plaintext_value = "%s"
resource "github_actions_secret" "plaintext_secret" {
repository = github_repository.test.name
secret_name = "test_plaintext_secret"
}

resource "github_actions_secret" "encrypted_secret" {
repository = github_repository.test.name
secret_name = "test_encrypted_secret"
}
`, randomID, secretValue)
`, randomID)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -183,5 +197,4 @@ func TestAccGithubActionsSecret(t *testing.T) {
})

})

}
Loading