Skip to content

Commit

Permalink
Added encrypted_value to Actions + Organizations's secrets (#807)
Browse files Browse the repository at this point in the history
* Added encrypted_value to Actions + Organizations's secrets

* Simplified unit tests

* Encrypted value needs to be in Base64 format

* Delete data_source_github_repository_branches.go
  • Loading branch information
threeseed authored Jun 8, 2021
1 parent 4f7109e commit fefa5b4
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 58 deletions.
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

0 comments on commit fefa5b4

Please sign in to comment.