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

azurerm_key_vault_certificate: expose arm resource id #21314

Merged
merged 4 commits into from
Apr 12, 2023
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
13 changes: 13 additions & 0 deletions internal/services/keyvault/key_vault_certificate_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ func dataSourceKeyVaultCertificate() *pluginsdk.Resource {
ValidateFunc: keyVaultValidate.VaultID,
},

"resource_manager_id": {
Computed: true,
Type: pluginsdk.TypeString,
},

"resource_manager_versionless_id": {
Computed: true,
Type: pluginsdk.TypeString,
},

"version": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -298,6 +308,9 @@ func dataSourceKeyVaultCertificateRead(d *pluginsdk.ResourceData, meta interface
d.Set("secret_id", cert.Sid)
d.Set("versionless_id", id.VersionlessID())

d.Set("resource_manager_id", parse.NewCertificateID(keyVaultId.SubscriptionId, keyVaultId.ResourceGroup, keyVaultId.Name, id.Name, id.Version).ID())
d.Set("resource_manager_versionless_id", parse.NewCertificateVersionlessID(keyVaultId.SubscriptionId, keyVaultId.ResourceGroup, keyVaultId.Name, id.Name).ID())

if cert.Sid != nil {
secretId, err := parse.ParseNestedItemID(*cert.Sid)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestAccDataSourceKeyVaultCertificate_basic(t *testing.T) {
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("certificate_data").Exists(),
check.That(data.ResourceName).Key("certificate_data_base64").Exists(),
check.That(data.ResourceName).Key("resource_manager_id").Exists(),
check.That(data.ResourceName).Key("resource_manager_versionless_id").Exists(),
check.That(data.ResourceName).Key("certificate_policy.0.key_properties.0.key_size").HasValue("2048"),
check.That(data.ResourceName).Key("certificate_policy.0.key_properties.0.key_type").HasValue("RSA"),
check.That(data.ResourceName).Key("not_before").HasValue("2017-10-10T08:27:55Z"),
Expand Down
13 changes: 13 additions & 0 deletions internal/services/keyvault/key_vault_certificate_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,16 @@ func resourceKeyVaultCertificate() *pluginsdk.Resource {
},
},

"resource_manager_id": {
Computed: true,
Type: pluginsdk.TypeString,
},

"resource_manager_versionless_id": {
Computed: true,
Type: pluginsdk.TypeString,
},

"version": {
Type: pluginsdk.TypeString,
Computed: true,
Expand Down Expand Up @@ -682,6 +692,9 @@ func resourceKeyVaultCertificateRead(d *pluginsdk.ResourceData, meta interface{}
d.Set("secret_id", cert.Sid)
d.Set("versionless_id", id.VersionlessID())

d.Set("resource_manager_id", parse.NewCertificateID(keyVaultId.SubscriptionId, keyVaultId.ResourceGroup, keyVaultId.Name, id.Name, id.Version).ID())
d.Set("resource_manager_versionless_id", parse.NewCertificateVersionlessID(keyVaultId.SubscriptionId, keyVaultId.ResourceGroup, keyVaultId.Name, id.Name).ID())

if cert.Sid != nil {
secretId, err := parse.ParseNestedItemID(*cert.Sid)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ func TestAccKeyVaultCertificate_basicImportPFX(t *testing.T) {
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("certificate_data").Exists(),
check.That(data.ResourceName).Key("resource_manager_id").Exists(),
check.That(data.ResourceName).Key("resource_manager_versionless_id").Exists(),
check.That(data.ResourceName).Key("certificate_data_base64").Exists(),
check.That(data.ResourceName).Key("certificate_policy.0.secret_properties.0.content_type").HasValue("application/x-pkcs12"),
check.That(data.ResourceName).Key("versionless_id").HasValue(fmt.Sprintf("https://acctestkeyvault%s.vault.azure.net/certificates/acctestcert%s", data.RandomString, data.RandomString)),
Expand Down
81 changes: 81 additions & 0 deletions internal/services/keyvault/parse/certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

type CertificateId struct {
SubscriptionId string
ResourceGroup string
VaultName string
Name string
VersionName string
}

func NewCertificateID(subscriptionId, resourceGroup, vaultName, name, versionName string) CertificateId {
return CertificateId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
VaultName: vaultName,
Name: name,
VersionName: versionName,
}
}

func (id CertificateId) String() string {
segments := []string{
fmt.Sprintf("Version Name %q", id.VersionName),
fmt.Sprintf("Name %q", id.Name),
fmt.Sprintf("Vault Name %q", id.VaultName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Certificate", segmentsStr)
}

func (id CertificateId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.KeyVault/vaults/%s/certificates/%s/versions/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.VaultName, id.Name, id.VersionName)
}

// CertificateID parses a Certificate ID into an CertificateId struct
func CertificateID(input string) (*CertificateId, error) {
id, err := resourceids.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := CertificateId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.VaultName, err = id.PopSegment("vaults"); err != nil {
return nil, err
}
if resourceId.Name, err = id.PopSegment("certificates"); err != nil {
return nil, err
}
if resourceId.VersionName, err = id.PopSegment("versions"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
144 changes: 144 additions & 0 deletions internal/services/keyvault/parse/certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

var _ resourceids.Id = CertificateId{}

func TestCertificateIDFormatter(t *testing.T) {
actual := NewCertificateID("12345678-1234-9876-4563-123456789012", "resGroup1", "vault1", "cert1", "version1").ID()
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/certificates/cert1/versions/version1"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestCertificateID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *CertificateId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing SubscriptionId
Input: "/",
Error: true,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Error: true,
},

{
// missing ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/",
Error: true,
},

{
// missing value for ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/",
Error: true,
},

{
// missing VaultName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/",
Error: true,
},

{
// missing value for VaultName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/",
Error: true,
},

{
// missing Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/",
Error: true,
},

{
// missing value for Name
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/certificates/",
Error: true,
},

{
// missing VersionName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/certificates/cert1/",
Error: true,
},

{
// missing value for VersionName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/certificates/cert1/versions/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.KeyVault/vaults/vault1/certificates/cert1/versions/version1",
Expected: &CertificateId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
ResourceGroup: "resGroup1",
VaultName: "vault1",
Name: "cert1",
VersionName: "version1",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.KEYVAULT/VAULTS/VAULT1/CERTIFICATES/CERT1/VERSIONS/VERSION1",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := CertificateID(v.Input)
if err != nil {
if v.Error {
continue
}

t.Fatalf("Expect a value but got an error: %s", err)
}
if v.Error {
t.Fatal("Expect an error but didn't get one")
}

if actual.SubscriptionId != v.Expected.SubscriptionId {
t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId)
}
if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup)
}
if actual.VaultName != v.Expected.VaultName {
t.Fatalf("Expected %q but got %q for VaultName", v.Expected.VaultName, actual.VaultName)
}
if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}
if actual.VersionName != v.Expected.VersionName {
t.Fatalf("Expected %q but got %q for VersionName", v.Expected.VersionName, actual.VersionName)
}
}
}
75 changes: 75 additions & 0 deletions internal/services/keyvault/parse/certificate_versionless.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

type CertificateVersionlessId struct {
SubscriptionId string
ResourceGroup string
VaultName string
CertificateName string
}

func NewCertificateVersionlessID(subscriptionId, resourceGroup, vaultName, certificateName string) CertificateVersionlessId {
return CertificateVersionlessId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
VaultName: vaultName,
CertificateName: certificateName,
}
}

func (id CertificateVersionlessId) String() string {
segments := []string{
fmt.Sprintf("Certificate Name %q", id.CertificateName),
fmt.Sprintf("Vault Name %q", id.VaultName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Certificate Versionless", segmentsStr)
}

func (id CertificateVersionlessId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.KeyVault/vaults/%s/certificates/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.VaultName, id.CertificateName)
}

// CertificateVersionlessID parses a CertificateVersionless ID into an CertificateVersionlessId struct
func CertificateVersionlessID(input string) (*CertificateVersionlessId, error) {
id, err := resourceids.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := CertificateVersionlessId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.VaultName, err = id.PopSegment("vaults"); err != nil {
return nil, err
}
if resourceId.CertificateName, err = id.PopSegment("certificates"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Loading