Skip to content

Commit

Permalink
Merge pull request #493 from Venafi/VC-32829/cucumber-tests-for-provi…
Browse files Browse the repository at this point in the history
…sioning-2

VC-32829 / Adds AWS cucumber tests for provisioning
  • Loading branch information
luispresuelVenafi committed Jun 6, 2024
2 parents aa37719 + 2609fc1 commit bbf788e
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 63 deletions.
5 changes: 3 additions & 2 deletions README-CLI-CLOUD.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,16 @@ Options:

| Command | Description |
|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--arn` | Use to specify AWS Resource Name which provisioned certificate will replace (only for AWS Certificate Manager) |
| `--certificate-id` | The id of the certificate to be provisioned to a cloud keystore. |
| `--certificate-id-file` | Use to specify a file name that contains the unique identifier of the certificate. Required when `--certificate-id` is not specified. |
| `--certificate-name` | Use to specify Cloud Keystore Certificate Name if it supports it |
| `--certificate-name` | Use to specify Cloud Keystore Certificate Name to be set or replaced by provisioned certificate (only for Azure Key Vault and Google Certificate Manager) |
| `--file` | Use to specify a file name and a location where the output should be written. Example: --file /path-to/provision-output |
| `--format` | The format of the operation output: text or JSON. Defaults to text. |
| `--keystore-id` | The id of the cloud keystore where the certificate will be provisioned. |
| `--keystore-name` | The name of the cloud keystore where the certificate will be provisioned. Must be set along with provider-name flag. |
| `--pickup-id-file` | Use to specify a file name that contains the unique identifier of the certificate returned by the enroll or renew actions if --no-pickup was used or a timeout occurred. Required when `--pickup-id` is not specified. |
| `--pickup-id` | Use to specify the unique identifier of the certificate returned by the enroll or renew actions. Required when `--pickup-id-file` is not specified. |
| `--pickup-id-file` | Use to specify a file name that contains the unique identifier of the certificate returned by the enroll or renew actions if --no-pickup was used or a timeout occurred. Required when `--pickup-id` is not specified. |
| `--provider-name` | The name of the cloud provider which owns the cloud keystore where the certificate will be provisioned. Must be set along with keystore-name flag. |

## Parameters for Applying Certificate Policy
Expand Down
1 change: 1 addition & 0 deletions aruba/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ MAINTAINER Venafi DevOps Integrations <[email protected]>

RUN gem install aruba json_spec
RUN gem install google-cloud-certificate_manager-v1
RUN gem install aws-sdk-acm
COPY . /vcert/
ENV BUNDLE_PATH="/vcert/tpp"
ENV GCP_AUTH_PATH="/vcert/cloud_providers"
Expand Down
8 changes: 7 additions & 1 deletion aruba/cucumber.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ RUN_COMMAND="docker run -t --rm \
-e GCP_REGION \
-e GCP_PROVIDER_NAME \
-e GCP_KEYSTORE_NAME \
-e GCP_KEYSTORE_ID"
-e GCP_KEYSTORE_ID \
-e AWS_ACCESS_KEY_ID \
-e AWS_REGION \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_PROVIDER_NAME \
-e AWS_KEYSTORE_NAME \
-e AWS_KEYSTORE_ID"

# Use getopts to handle command-line options
while getopts "a:b:" opt; do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,38 @@ Feature: provision to cloud keystore
And I remember the output
And I use previous Pickup ID to provision from VCP a certificate to cloudkeystore "<cloudkeystore>" setting keystore and provider names
And I remember the output
And it should output cloud ID
And I grab cloud ID from output
Then I clean up previous installed certificate from cloudkeystore
Examples:
| cloudkeystore |
| GOOGLE |
| AWS |

Scenario Outline: Enroll certificate and execute provisioning for cloud keystore and get output in JSON
Given I enroll a random certificate with defined platform VCP with -csr service -no-prompt
And I remember the output
And I use previous Pickup ID to provision from VCP a certificate to cloudkeystore "<cloudkeystore>" setting keystore and provider names with -format json
And I remember the output
And it should output cloud ID in JSON
And I grab cloud ID from JSON output
Then I clean up previous installed certificate from cloudkeystore
Examples:
| cloudkeystore |
| GOOGLE |
| AWS |

Scenario Outline: Enroll certificate, execute provisioning and then provisioning again for replace
Given I enroll a random certificate with defined platform VCP with -csr service -no-prompt
And I remember the output
And I use previous Pickup ID to provision from VCP a certificate to cloudkeystore "<cloudkeystore>" setting keystore and provider names
And I remember the output
And the output should contain "cloudId:"
And the output should contain "machineIdentityActionType: New"
And I grab cloud ID from output
Then I use previous Pickup ID and cloud ID to provision again
And I remember the output
And the output should contain the previous cloud ID
And the output should contain "machineIdentityActionType: ReProvision"
Then I clean up previous installed certificate from cloudkeystore
Examples:
| cloudkeystore |
| AWS |
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@
steps %{Then I try to run `#{cmd}`}
end

And(/^I use previous Pickup ID and cloud ID to provision again$/) do
keystore_provider_names = true
flags = ""
if @cloudkeystore_type == $keystore_type_aws
flags += " -arn #{@cloud_id}"
elsif @cloudkeystore_type == $keystore_type_azure or @cloudkeystore_type == $keystore_type_gcp
flags += " -certificate-name #{@cloud_id}"
end
flags += @global_set_provision_flags
cmd = build_provision_cmd($platform_vcp, @cloudkeystore_type, keystore_provider_names, flags)
steps %{Then I try to run `#{cmd}`}
end

def build_provision_cmd(platform, cloudkeystore_type, keystore_provider_names, flags = "")

@global_set_provision_flags = flags

platform_flag = " -platform " + platform

cmd = "vcert provision cloudkeystore #{platform_flag} #{ENDPOINTS[$platform_vcp]} -pickup-id #{@pickup_id}"
Expand All @@ -22,7 +37,14 @@ def build_provision_cmd(platform, cloudkeystore_type, keystore_provider_names, f
provider_name = ""
keystore_id = ""
case cloudkeystore_type
when $keystore_type_azure
when $keystore_type_aws
if keystore_provider_names
keystore_name = $aws_keystore_name
provider_name = $aws_provider_name
@cloudkeystore_type = $keystore_type_aws
else
keystore_name = $aws_keystore_id
end
when $keystore_type_gcp
if keystore_provider_names
keystore_name = $gcp_keystore_name
Expand Down Expand Up @@ -51,45 +73,75 @@ def build_provision_cmd(platform, cloudkeystore_type, keystore_provider_names, f
return cmd
end

Then(/^it should output cloud ID( in JSON)?$/) do |json|
Then(/^I grab cloud ID from( JSON)? output$/) do |json|

@cloud_id = get_cloud_id_from_output(json)

end

def get_cloud_id_from_output(json = false)
if @previous_command_output.nil?
fail(ArgumentError.new('@previous_command_output is nil'))
end

Kernel.puts("Checking output:\n"+@previous_command_output)
cloud_id = ""
case @cloudkeystore_type
when $keystore_type_aws
when $keystore_type_azure
when $keystore_type_gcp
cloud_id = "gcpId"
else
fail(ArgumentError.new("Unexpected : #{@cloudkeystore_type}"))
end
cloud_id_attr = "cloudId"

if json
json_string = extract_json_from_output(@previous_command_output)
JSON.parse(json_string)
@cloud_id = unescape_text(normalize_json(json_string, "#{cloud_id}")).tr('"', '')
cloud_id = unescape_text(normalize_json(json_string, "#{cloud_id_attr}")).tr('"', '')
else
m = @previous_command_output.match /#{cloud_id} (.+)$/
@cloud_id = m[1]
m = @previous_command_output.match /#{cloud_id_attr}: (.+)$/
cloud_id = m[1]
end
cloud_id
end

Then(/^the output( in JSON)? should contain the previous cloud ID$/) do |json|
old_cloud_id = @cloud_id
new_cloud_id = get_cloud_id_from_output(json)
if old_cloud_id != new_cloud_id
cleanup_keystore(old_cloud_id)
cleanup_keystore(new_cloud_id)
fail(ArgumentError.new("Expected old Cloud ID: #{old_cloud_id} to be same as new Cloud ID, but got: #{new_cloud_id}"))
end
end

And(/^I clean up previous installed certificate from cloudkeystore/) do ||
cleanup_keystore
end

def cleanup_keystore(cloud_id = "")
case @cloudkeystore_type
when $keystore_type_aws
cleanup_aws(cloud_id)
when $keystore_type_azure
when $keystore_type_gcp
cleanup_google
cleanup_google(cloud_id)
else
fail(ArgumentError.new("Unexpected : #{@cloudkeystore_type}"))
end
end

def cleanup_google
client = create_certificate_manager_client
certificate_name = "projects/#{ENV['GCP_PROJECT']}/locations/#{ENV['GCP_REGION']}/certificates/#{@cloud_id}"
delete_certificate(client, certificate_name)
def cleanup_google(cloud_id = "")
client = create_google_certificate_manager_client
if cloud_id != ""
certificate_name = "projects/#{ENV['GCP_PROJECT']}/locations/#{ENV['GCP_REGION']}/certificates/#{cloud_id}"
else
certificate_name = "projects/#{ENV['GCP_PROJECT']}/locations/#{ENV['GCP_REGION']}/certificates/#{@cloud_id}"
end

delete_gcm_certificate(client, certificate_name)
end

def cleanup_aws(cloud_id = "")
client = create_aws_certificate_manager_client
if cloud_id != ""
certificate_arn = cloud_id
else
certificate_arn = @cloud_id
end

delete_acm_certificate(client, certificate_arn)
end
4 changes: 4 additions & 0 deletions aruba/features/support/aruba.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
$gcp_keystore_name = ENV["GCP_KEYSTORE_NAME"]
$gcp_provider_name = ENV["GCP_PROVIDER_NAME"]

$aws_keystore_id = ENV["AWS_KEYSTORE_ID"]
$aws_keystore_name = ENV["AWS_KEYSTORE_NAME"]
$aws_provider_name = ENV["AWS_PROVIDER_NAME"]

def last_json
last_command_started.stdout.to_s
end
Expand Down
20 changes: 20 additions & 0 deletions aruba/features/support/aws_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'aws-sdk-acm'

# Initialize the Certificate Manager Client
def create_aws_certificate_manager_client
Aws::ACM::Client.new(
region: ENV['AWS_REGION'],
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
)
end

# Delete a certificate
def delete_acm_certificate(client, certificate_arn)
begin
client.delete_certificate({ certificate_arn: certificate_arn })
puts "Certificate with ARN #{certificate_arn} deleted successfully."
rescue Aws::ACM::Errors::ServiceError => e
puts "Error deleting certificate: #{e.message}"
end
end
4 changes: 2 additions & 2 deletions aruba/features/support/google_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = ENV['GCP_AUTH_PATH']

# Initialize the Certificate Manager Client
def create_certificate_manager_client
def create_google_certificate_manager_client
Google::Cloud::CertificateManager::V1::CertificateManager::Client.new
end

# Delete a certificate
def delete_certificate(client, certificate_name)
def delete_gcm_certificate(client, certificate_name)
request = Google::Cloud::CertificateManager::V1::DeleteCertificateRequest.new(
name: certificate_name
)
Expand Down
1 change: 1 addition & 0 deletions cmd/vcert/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ type commandFlags struct {
providerName string
keystoreName string
keystoreCertName string
keystoreARN string
provisionOutputFile string
provisionPickupID string
provisionFormat string
Expand Down
7 changes: 3 additions & 4 deletions cmd/vcert/cmdCloudKeystores.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,20 @@ func doCommandProvisionCloudKeystore(c *cli.Context) error {
MachineIdentityId: metadata.MachineIdentityID,
MachineIdentityActionType: metadata.MachineIdentityActionType,
}
result.CloudID = metadata.CertificateID
switch metadata.CloudKeystoreType {
case domain.CloudKeystoreTypeACM:
result.ARN = metadata.CertificateID
// do nothing
case domain.CloudKeystoreTypeAKV:
result.AzureID = metadata.CertificateID
result.AzureName = metadata.CertificateName
result.AzureVersion = metadata.CertificateVersion
case domain.CloudKeystoreTypeGCM:
result.GcpID = metadata.CertificateID
result.GcpName = metadata.CertificateName
default:
return fmt.Errorf("unknown keystore metadata type: %s", metadata.CloudKeystoreType)
}

err = result.Flush(flags.provisionFormat, flags.provisionOutputFile)
err = result.Flush(flags.provisionFormat, flags.provisionOutputFile, metadata.CloudKeystoreType)
if err != nil {
return fmt.Errorf("failed to output the results: %s", err)
}
Expand Down
19 changes: 13 additions & 6 deletions cmd/vcert/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -741,10 +741,16 @@ var (

flagKeystoreCertName = &cli.StringFlag{
Name: "certificate-name",
Usage: "Use to specify Cloud Keystore Certificate Name if it supports it",
Usage: "Use to specify Cloud Keystore Certificate Name to be set or replaced by provisioned certificate (only for Azure Key Vault and Google Certificate Manager)",
Destination: &flags.keystoreCertName,
}

flagKeystoreARN = &cli.StringFlag{
Name: "arn",
Usage: "Use to specify AWS Resource Name which provisioned certificate will replace (only for AWS Certificate Manager)",
Destination: &flags.keystoreARN,
}

flagProvisionOutputFile = &cli.StringFlag{
Name: "file",
Usage: "Use to specify a file name and a location where the output should be written. " +
Expand Down Expand Up @@ -906,16 +912,17 @@ var (
provisionFlags = flagsApppend(
credentialsFlags,
flagPlatform,
flagKeystoreARN,
flagCertificateID,
flagCertificateIDFile,
flagKeystoreCertName,
flagProvisionOutputFile,
flagProvisionFormat,
flagKeystoreID,
flagKeystoreName,
flagProvisionPickupID,
flagPickupIDFile,
flagKeystoreCertName,
flagProviderName,
flagKeystoreName,
flagKeystoreID,
flagProvisionFormat,
flagProvisionOutputFile,
)

commonCredFlags = []cli.Flag{flagConfig, flagProfile, flagUrl, flagToken, flagTrustBundle}
Expand Down
Loading

0 comments on commit bbf788e

Please sign in to comment.