Skip to content

Commit 8d3dffb

Browse files
committed
fix(data): keyfactor_certificate data sources allow passing collectionID to lookup
1 parent 0b95ac8 commit 8d3dffb

3 files changed

Lines changed: 59 additions & 15 deletions

File tree

internal/provider/v3/command/certificate_helpers.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -290,18 +290,24 @@ func recoverPrivateKey(ctx context.Context, client *kfc.APIClient, id int64, thu
290290
return "", nil, nil, fmt.Errorf("failed to recover private key for certificate")
291291
}
292292

293-
func readCertificateById(ctx context.Context, cID int, client *kfc.APIClient) (*kfc.ModelsCertificateRetrievalResponse, *http.Response, error) {
293+
func readCertificateById(ctx context.Context, cID int, client *kfc.APIClient, collectionID int64) (*kfc.ModelsCertificateRetrievalResponse, *http.Response, error) {
294294
ctx = tflog.SetField(ctx, "certificate_id", cID)
295295
tflog.Debug(ctx, fmt.Sprintf("Calling GET %s/Certificate/%d", client.GetConfig().Host, cID))
296-
clientResp, httpResp, respErr := client.CertificateApi.CertificateGetCertificate(ctx, int32(cID)).
296+
req := client.CertificateApi.CertificateGetCertificate(ctx, int32(cID)).
297297
IncludeMetadata(true).
298-
IncludeLocations(true).
299-
Execute()
298+
IncludeLocations(true)
299+
300+
if collectionID > 0 {
301+
ctx = tflog.SetField(ctx, "collection_id", collectionID)
302+
tflog.Debug(ctx, "Adding collection_id to request")
303+
req.CollectionId(int32(collectionID))
304+
}
305+
clientResp, httpResp, respErr := req.Execute()
300306
logCommandAPIResponse(ctx, httpResp, respErr)
301307

302308
if httpResp.StatusCode == http.StatusNotFound {
303309
tflog.Warn(ctx, fmt.Sprintf("Unable to find certificate %d using Keyfactor Command certificate Id. Attempting to search as serial number.", cID))
304-
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateSNFieldName, fmt.Sprintf("%d", cID), client)
310+
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateSNFieldName, fmt.Sprintf("%d", cID), client, collectionID)
305311
}
306312

307313
var (
@@ -311,20 +317,20 @@ func readCertificateById(ctx context.Context, cID int, client *kfc.APIClient) (*
311317
)
312318
tp := clientResp.Thumbprint
313319
if tp != nil {
314-
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateThumbprintFieldName, tp, client)
320+
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateThumbprintFieldName, tp, client, collectionID)
315321
} else {
316322
tflog.Warn(ctx, fmt.Sprintf("Thumbprint for certificate %d is nil. Attempting to search as serial number.", cID))
317323
sn := clientResp.SerialNumber
318324
if sn == nil {
319325
tflog.Warn(ctx, fmt.Sprintf("Serial number for certificate %d is nil. Attempting to search as Issuer DN.", cID))
320326
dn := clientResp.IssuedDN
321327
if dn.IsSet() {
322-
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateDNFieldName, dn, client)
328+
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateDNFieldName, dn, client, collectionID)
323329
} else {
324330
tflog.Warn(ctx, fmt.Sprintf("Unable to lookup locations, private key and metadata for %d", cID))
325331
}
326332
} else {
327-
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateSNFieldName, sn, client)
333+
detailedClientResp, detailedHttpResp, detailedRespErr = lookupCertificate(ctx, CertificateSNFieldName, sn, client, collectionID)
328334
}
329335
}
330336
if detailedClientResp != nil && detailedRespErr == nil {
@@ -338,11 +344,12 @@ func readCertificateById(ctx context.Context, cID int, client *kfc.APIClient) (*
338344
return clientResp, httpResp, respErr
339345
}
340346

341-
func lookupCertificate(ctx context.Context, fieldName string, fieldValue interface{}, client *kfc.APIClient) (*kfc.ModelsCertificateRetrievalResponse, *http.Response, error) {
347+
func lookupCertificate(ctx context.Context, fieldName string, fieldValue interface{}, client *kfc.APIClient, collectionId int64) (*kfc.ModelsCertificateRetrievalResponse, *http.Response, error) {
342348
var (
343349
q string
344350
notFoundErr error
345351
)
352+
346353
switch fieldValue.(type) {
347354
case string:
348355
q = fmt.Sprintf(`%s -eq "%s"`, fieldName, fieldValue.(string))
@@ -367,12 +374,18 @@ func lookupCertificate(ctx context.Context, fieldName string, fieldValue interfa
367374
tflog.Info(ctx, fmt.Sprintf("Looking up cert by '%s'", fieldName))
368375
ctx = tflog.SetField(ctx, "query_string", q)
369376
tflog.Debug(ctx, fmt.Sprintf("Calling GET %s/Certificate?QueryString=%s", client.GetConfig().Host, q))
370-
certsResp, httpResp, respErr := client.CertificateApi.CertificateQueryCertificates(ctx).
377+
req := client.CertificateApi.CertificateQueryCertificates(ctx).
371378
IncludeMetadata(true).
372379
IncludeLocations(true).
373380
IncludeHasPrivateKey(true).
374-
PqQueryString(q).
375-
Execute()
381+
PqQueryString(q)
382+
if collectionId > 0 {
383+
ctx = tflog.SetField(ctx, "collection_id", collectionId)
384+
tflog.Debug(ctx, fmt.Sprintf("Adding collection_id to request"))
385+
req.CollectionId(int32(collectionId))
386+
}
387+
certsResp, httpResp, respErr := req.Execute()
388+
376389
logCommandAPIResponse(ctx, httpResp, respErr)
377390

378391
if len(certsResp) > 0 {

internal/provider/v3/command/data_source_keyfactor_certificate.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ func (d *CertificateDataSource) Read(ctx context.Context, req datasource.ReadReq
541541
}
542542

543543
certIdentifier := data.Identifier.ValueString()
544+
collectionId := data.CollectionId.ValueInt64()
544545
ctx = tflog.SetField(ctx, "certificate_identifier", certIdentifier)
545546

546547
// If the `identifier` attribute is an integer, use it to query the certificate
@@ -551,11 +552,11 @@ func (d *CertificateDataSource) Read(ctx context.Context, req datasource.ReadReq
551552
)
552553

553554
if cID, ok := strconv.Atoi(certIdentifier); ok == nil {
554-
clientResp, httpResp, respErr = readCertificateById(ctx, cID, d.client)
555+
clientResp, httpResp, respErr = readCertificateById(ctx, cID, d.client, collectionId)
555556
} else if len(certIdentifier) == CertificateThumbprintLength {
556-
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateThumbprintFieldName, certIdentifier, d.client)
557+
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateThumbprintFieldName, certIdentifier, d.client, collectionId)
557558
} else {
558-
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateCNFieldName, certIdentifier, d.client)
559+
clientResp, httpResp, respErr = lookupCertificate(ctx, CertificateCNFieldName, certIdentifier, d.client, collectionId)
559560
}
560561
if clientResp == nil {
561562
resp.Diagnostics.AddError("Invalid Certificate Identifier", fmt.Sprintf("Unable to find certificate %s in Keyfactor Command", certIdentifier))

internal/provider/v3/command/data_source_keyfactor_certificate_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import (
55
"github.com/hashicorp/terraform-plugin-framework/attr"
66
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
77
"os"
8+
"strconv"
89
"testing"
910
)
1011

1112
func TestAccKeyfactorCertificateDataSource(t *testing.T) {
1213
var resourceName = fmt.Sprintf("data.%s.test", "keyfactor_certificate")
1314
var cID = os.Getenv("TEST_CERTIFICATE_ID")
15+
var colID = os.Getenv("TEST_CERTIFICATE_COLLECTION_ID")
1416
var cCN = os.Getenv("TEST_CERTIFICATE_CN")
1517
var cTP = os.Getenv("TEST_CERTIFICATE_THUMBPRINT")
1618
var caID = os.Getenv("TEST_CERTIFICATE_AUTHORITY_CERT_ID")
@@ -30,6 +32,10 @@ func TestAccKeyfactorCertificateDataSource(t *testing.T) {
3032
if cTP == "" {
3133
t.Log("TEST_CERTIFICATE_THUMBPRINT is not set, skipping TestAccKeyfactorCertificateDataSource")
3234
}
35+
if colID == "" {
36+
colID = "0"
37+
}
38+
colIDInt, _ := strconv.Atoi(colID)
3339
resource.Test(t, resource.TestCase{
3440
PreCheck: func() { testAccPreCheck(t) },
3541
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
@@ -51,6 +57,18 @@ func TestAccKeyfactorCertificateDataSource(t *testing.T) {
5157
Config: testAccDataSourceKeyfactorCertificateBasic(t, cID, "hi"),
5258
Check: certTestValidateAll(resourceName),
5359
},
60+
{
61+
// Test lookup containing collection ID
62+
// TODO: This needs to have limited access to properly test
63+
Config: testAccDataSourceKeyfactorCertificateCollectionId(t, cID, password, colIDInt),
64+
Check: certTestValidateAll(resourceName),
65+
},
66+
{
67+
// Test lookup containing invalid collection ID
68+
// TODO: This needs to have limited access to properly test
69+
Config: testAccDataSourceKeyfactorCertificateCollectionId(t, cID, password, 9999),
70+
Check: certTestValidateAll(resourceName),
71+
},
5472
{
5573
// Test lookup by CN
5674
Config: testAccDataSourceKeyfactorCertificateBasic(t, cCN, password),
@@ -81,6 +99,18 @@ func testAccDataSourceKeyfactorCertificateBasic(t *testing.T, resourceId string,
8199
return output
82100
}
83101

102+
func testAccDataSourceKeyfactorCertificateCollectionId(t *testing.T, resourceId string, password string, collectionId int) string {
103+
output := fmt.Sprintf(`
104+
data "keyfactor_certificate" "test" {
105+
identifier = "%s"
106+
key_password = "%s"
107+
collection_id = "%d"
108+
}
109+
`, resourceId, password, collectionId)
110+
t.Logf("%s", output)
111+
return output
112+
}
113+
84114
func certTestValidateAll(resourceName string) resource.TestCheckFunc {
85115
return resource.ComposeAggregateTestCheckFunc(
86116
resource.TestCheckResourceAttrSet(resourceName, "archived_key"),

0 commit comments

Comments
 (0)