-
Notifications
You must be signed in to change notification settings - Fork 29
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
feat(build): Add KMIP Management APIs to Go SDK #122
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
765acef
rename keyring path for conflicts
MDarmawan c6db64d
initial implementation of adapters and certs
MDarmawan db76a5e
add kmip objects, fix some stuff
MDarmawan f89ec78
fix structs
MDarmawan 60a6f26
unit tests, and some fixes
MDarmawan fc64449
remove import cycle
MDarmawan f5d47f2
redo mocks
MDarmawan b1a9076
add mockauth
MDarmawan 54234af
fix mobk paths
MDarmawan 9d725f5
fix marshalling
MDarmawan fc7c099
fix delete tests
MDarmawan ffee250
remove old kmip profile data
MDarmawan f0725c0
address PR comments
MDarmawan 1628c46
finish address comments
MDarmawan 2ee3160
hardcode mock responses, refactor kmip collection metadata
MDarmawan 4d8bfaa
fix tests?
MDarmawan ed29fed
fix typo
MDarmawan 7ba8c86
add object filter, overhaul list options
MDarmawan d12983c
enhance tests
MDarmawan 49d26b1
unexport path variables, add comments
MDarmawan b6baf18
sdk fixes
MDarmawan 03b45ba
remove crk from adapter list
MDarmawan 603c5c2
remove commented code
MDarmawan c936037
fix tests from changes
MDarmawan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package kp | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
) | ||
|
||
const ( | ||
kmipAdapterPath = "kmip_adapters" | ||
kmipAdapterType = "application/vnd.ibm.kms.kmip_adapter+json" | ||
) | ||
|
||
type KMIPAdapter struct { | ||
ID string `json:"id,omitempty"` | ||
Profile string `json:"profile,omitempty"` | ||
ProfileData map[string]string `json:"profile_data,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
Description string `json:"description"` | ||
CreatedBy string `json:"created_by,omitempty"` | ||
CreatedAt *time.Time `json:"created_at,omitempty"` | ||
UpdatedBy string `json:"updated_by,omitempty"` | ||
UpdatedAt *time.Time `json:"updated_at,omitempty"` | ||
} | ||
|
||
type KMIPAdapters struct { | ||
Metadata CollectionMetadata `json:"metadata"` | ||
Adapters []KMIPAdapter `json:"resources"` | ||
} | ||
|
||
const ( | ||
KMIP_Profile_Native = "native_1.0" | ||
) | ||
|
||
// CreateKMIPAdapter method creates a KMIP Adapter with the specified profile. | ||
func (c *Client) CreateKMIPAdapter(ctx context.Context, profileOpt CreateKMIPAdapterProfile, options ...CreateKMIPAdapterOption) (*KMIPAdapter, error) { | ||
newAdapter := &KMIPAdapter{} | ||
profileOpt(newAdapter) | ||
for _, opt := range options { | ||
opt(newAdapter) | ||
} | ||
req, err := c.newRequest("POST", kmipAdapterPath, wrapKMIPAdapter(*newAdapter)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
create_resp := &KMIPAdapters{} | ||
_, err = c.do(ctx, req, create_resp) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return unwrapKMIPAdapterResp(create_resp), nil | ||
} | ||
|
||
// Functions to be passed into the CreateKMIPAdapter() method to specify specific fields. | ||
type CreateKMIPAdapterOption func(*KMIPAdapter) | ||
type CreateKMIPAdapterProfile func(*KMIPAdapter) | ||
|
||
func WithKMIPAdapterName(name string) CreateKMIPAdapterOption { | ||
return func(adapter *KMIPAdapter) { | ||
adapter.Name = name | ||
} | ||
} | ||
|
||
func WithKMIPAdapterDescription(description string) CreateKMIPAdapterOption { | ||
return func(adapter *KMIPAdapter) { | ||
adapter.Description = description | ||
} | ||
} | ||
|
||
func WithNativeProfile(crkID string) CreateKMIPAdapterProfile { | ||
return func(adapter *KMIPAdapter) { | ||
adapter.Profile = KMIP_Profile_Native | ||
|
||
adapter.ProfileData = map[string]string{ | ||
"crk_id": crkID, | ||
} | ||
} | ||
} | ||
|
||
type ListKmipAdaptersOptions struct { | ||
Limit *uint32 | ||
Offset *uint32 | ||
TotalCount *bool | ||
} | ||
|
||
// GetKMIPAdapters method lists KMIP Adapters associated with a specific KP instance. | ||
func (c *Client) GetKMIPAdapters(ctx context.Context, listOpts *ListKmipAdaptersOptions) (*KMIPAdapters, error) { | ||
adapters := KMIPAdapters{} | ||
req, err := c.newRequest("GET", kmipAdapterPath, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if listOpts != nil { | ||
values := req.URL.Query() | ||
if listOpts.Limit != nil { | ||
values.Set("limit", fmt.Sprint(*listOpts.Limit)) | ||
} | ||
if listOpts.Offset != nil { | ||
values.Set("offset", fmt.Sprint(*listOpts.Offset)) | ||
} | ||
if listOpts.TotalCount != nil { | ||
values.Set("totalCount", fmt.Sprint(*listOpts.TotalCount)) | ||
} | ||
req.URL.RawQuery = values.Encode() | ||
} | ||
|
||
_, err = c.do(ctx, req, &adapters) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &adapters, nil | ||
} | ||
|
||
// GetKMIPAdapter method retrieves a single KMIP Adapter by name or ID. | ||
func (c *Client) GetKMIPAdapter(ctx context.Context, nameOrID string) (*KMIPAdapter, error) { | ||
adapters := KMIPAdapters{} | ||
req, err := c.newRequest("GET", fmt.Sprintf("%s/%s", kmipAdapterPath, nameOrID), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
_, err = c.do(ctx, req, &adapters) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return unwrapKMIPAdapterResp(&adapters), nil | ||
} | ||
|
||
// DeletesKMIPAdapter method deletes a single KMIP Adapter by name or ID. | ||
func (c *Client) DeleteKMIPAdapter(ctx context.Context, nameOrID string) error { | ||
req, err := c.newRequest("DELETE", fmt.Sprintf("%s/%s", kmipAdapterPath, nameOrID), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = c.do(ctx, req, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func wrapKMIPAdapter(adapter KMIPAdapter) KMIPAdapters { | ||
return KMIPAdapters{ | ||
Metadata: CollectionMetadata{ | ||
CollectionType: kmipAdapterType, | ||
CollectionTotal: 1, | ||
}, | ||
Adapters: []KMIPAdapter{adapter}, | ||
} | ||
} | ||
|
||
func unwrapKMIPAdapterResp(resp *KMIPAdapters) *KMIPAdapter { | ||
return &resp.Adapters[0] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package kp | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
) | ||
|
||
const ( | ||
kmipClientCertSubPath = "certificates" | ||
kmipClientCertType = "application/vnd.ibm.kms.kmip_client_certificate+json" | ||
) | ||
|
||
type KMIPClientCertificate struct { | ||
ID string `json:"id,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
Certificate string `json:"certificate,omitempty"` | ||
CreatedBy string `json:"created_by,omitempty"` | ||
CreatedAt *time.Time `json:"created_at,omitempty"` | ||
} | ||
|
||
type KMIPClientCertificates struct { | ||
Metadata CollectionMetadata `json:"metadata"` | ||
Certificates []KMIPClientCertificate `json:"resources"` | ||
} | ||
|
||
// CreateKMIPClientCertificate registers/creates a KMIP PEM format certificate | ||
// for use with a specific KMIP adapter. | ||
// cert_payload is the string representation of | ||
// the certificate to be associated with the KMIP Adapter in PEM format. | ||
// It should explicitly have the BEGIN CERTIFICATE and END CERTIFICATE tags. | ||
// Regex: ^\s*-----BEGIN CERTIFICATE-----[A-Za-z0-9+\/\=\r\n]+-----END CERTIFICATE-----\s*$ | ||
func (c *Client) CreateKMIPClientCertificate(ctx context.Context, adapter_nameOrID, cert_payload string, opts ...CreateKMIPClientCertOption) (*KMIPClientCertificate, error) { | ||
newCert := &KMIPClientCertificate{ | ||
Certificate: cert_payload, | ||
} | ||
for _, opt := range opts { | ||
opt(newCert) | ||
} | ||
req, err := c.newRequest("POST", fmt.Sprintf("%s/%s/%s", kmipAdapterPath, adapter_nameOrID, kmipClientCertSubPath), wrapKMIPClientCert(*newCert)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
certResp := &KMIPClientCertificates{} | ||
_, err = c.do(ctx, req, certResp) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return unwrapKMIPClientCert(certResp), nil | ||
} | ||
|
||
type CreateKMIPClientCertOption func(*KMIPClientCertificate) | ||
|
||
func WithKMIPClientCertName(name string) CreateKMIPClientCertOption { | ||
return func(cert *KMIPClientCertificate) { | ||
cert.Name = name | ||
} | ||
} | ||
|
||
// GetKMIPClientCertificates lists all certificates associated with a KMIP adapter | ||
func (c *Client) GetKMIPClientCertificates(ctx context.Context, adapter_nameOrID string, listOpts *ListOptions) (*KMIPClientCertificates, error) { | ||
certs := KMIPClientCertificates{} | ||
req, err := c.newRequest("GET", fmt.Sprintf("%s/%s/%s", kmipAdapterPath, adapter_nameOrID, kmipClientCertSubPath), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if listOpts != nil { | ||
values := req.URL.Query() | ||
if listOpts.Limit != nil { | ||
values.Set("limit", fmt.Sprint(*listOpts.Limit)) | ||
} | ||
if listOpts.Offset != nil { | ||
values.Set("offset", fmt.Sprint(*listOpts.Offset)) | ||
} | ||
if listOpts.TotalCount != nil { | ||
values.Set("totalCount", fmt.Sprint(*listOpts.TotalCount)) | ||
} | ||
req.URL.RawQuery = values.Encode() | ||
} | ||
|
||
_, err = c.do(ctx, req, &certs) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &certs, nil | ||
} | ||
|
||
// GetKMIPClientCertificate gets a single certificate associated with a KMIP adapter | ||
func (c *Client) GetKMIPClientCertificate(ctx context.Context, adapter_nameOrID, cert_nameOrID string) (*KMIPClientCertificate, error) { | ||
certs := &KMIPClientCertificates{} | ||
req, err := c.newRequest("GET", fmt.Sprintf("%s/%s/%s/%s", | ||
kmipAdapterPath, adapter_nameOrID, kmipClientCertSubPath, cert_nameOrID), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
_, err = c.do(ctx, req, certs) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return unwrapKMIPClientCert(certs), nil | ||
} | ||
|
||
// DeleteKMIPClientCertificate deletes a single certificate | ||
func (c *Client) DeleteKMIPClientCertificate(ctx context.Context, adapter_nameOrID, cert_nameOrID string) error { | ||
req, err := c.newRequest("DELETE", fmt.Sprintf("%s/%s/%s/%s", | ||
kmipAdapterPath, adapter_nameOrID, kmipClientCertSubPath, cert_nameOrID), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = c.do(ctx, req, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func wrapKMIPClientCert(cert KMIPClientCertificate) KMIPClientCertificates { | ||
return KMIPClientCertificates{ | ||
Metadata: CollectionMetadata{ | ||
CollectionType: kmipClientCertType, | ||
CollectionTotal: 1, | ||
}, | ||
Certificates: []KMIPClientCertificate{cert}, | ||
} | ||
} | ||
|
||
func unwrapKMIPClientCert(certs *KMIPClientCertificates) *KMIPClientCertificate { | ||
return &certs.Certificates[0] | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were we not able to reuse
ListOptions
? Noticed this was a change from last reviewThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using its own struct type in order to allow for extensibility, adding new options to list kmip adapters