hashicorp / packer-plugin-vsphere

Packer plugin for VMware vSphere Builder
https://www.packer.io/docs/builders/vsphere
Mozilla Public License 2.0
93 stars 91 forks source link

feat: import ovf template from url in supervisor builder #433

Closed ericvmw closed 2 weeks ago

ericvmw commented 1 month ago

Summary

A new feature is being added to Supervisors to expose a new custom resource ContentLibraryItemImportRequest that allows users to import OVF templates to a namespace with writable & import-allowed content library configured on a Supervisor, this enables users to use Packer to orchestrate a complete e2e workflow, from importing their source image from HTTP server, to customize and publish the image to Supervisor clusters.

This change adds configurable optional steps on supervisor builder plugin to allow users to import OVF template to Supervisor namespaces via packer builder vsphere supervisor plugin.

  1. Add import image step to import image from remote URL to the target content library in the specified namespace on the Supervisor by creating ContentLibraryItemImportRequest resource, wait until the import request completes. If keep_input_artifact is set to be true, the import request will be cleaned after it is done. Besides taking the image_name config from existing CreateSource step, this step also support the following optional configs: import_source_url: the remote URL to import OVF template from, must starts with https. import_source_ssl_certificate: the SSL certificate of the remote HTTPS server. import_target_location_name: the import target location (content library that must be writable and allow import). import_target_image_type: optional, the target image type, it defaults to OVF type and only OVF type is supported currently. import_request_name: The name of the ContentLibraryItemImportRequest resource, otherwise it defaults to packer-vsphere-supervisor-import-req-<random-suffix>. watch_import_timeout_sec: The timeout in seconds to wait for the image to be imported, otherwise it defaults to 600. clean_imported_image: optional, whether to clean the image imported in this step. If it is set to true, the imported image will be deleted after source VM is created and becomes ready. Defaults to false.

  2. Add unit tests to cover both import validation and import image steps.

Note that in order to import OVF template from remote URL, the target content library must be configured with the default OVF security policy, and the OVF template must be signed with a certificated that is signed by a CA cert trusted by Content Library Service on vCenter, otherwise the import OVF template image will not be security compliant and cannot be deployed.

Testing

Testing Done:
~/Git/github.com/hashicorp/packer-plugin-vsphere   feat/import-ovf-from-url-on-supervisor
 $ go fmt ./...

~/Git/github.com/hashicorp/packer-plugin-vsphere   feat/import-ovf-from-url-on-supervisor
 $ make generate
2024/05/15 10:36:18 Copying "docs" to ".docs/"
2024/05/15 10:36:18 Replacing @include '...' calls in .docs/ Compiling MDX docs in '.docs' to Markdown in '.web-docs'...

~/Git/github.com/hashicorp/packer-plugin-vsphere   feat/import-ovf-from-url-on-supervisor
 $ make build

~/Git/github.com/hashicorp/packer-plugin-vsphere   feat/import-ovf-from-url-on-supervisor
 $ make test
?       github.com/hashicorp/packer-plugin-vsphere  [no test files]
?       github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/common/testing   [no test files]
?       github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/examples/driver  [no test files]
?       github.com/hashicorp/packer-plugin-vsphere/version  [no test files]
ok      github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/clone    2.033s
ok      github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/common   3.404s
ok      github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/driver   4.862s
ok      github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/iso  2.362s
ok      github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/supervisor   5.488s
ok      github.com/hashicorp/packer-plugin-vsphere/post-processor/vsphere   1.651s
ok      github.com/hashicorp/packer-plugin-vsphere/post-processor/vsphere-template  2.766s

added unit tests pass:

=== RUN   TestImportImage_Prepare
--- PASS: TestImportImage_Prepare (0.00s)
=== RUN   TestStepImportImage_Run_Skip
2024/05/17 14:58:41 ui: Skipping image import step. Required configurations for the import are not set.
2024/05/17 14:58:41 ui: Skipping image import step. Required configurations for the import are not set.
--- PASS: TestStepImportImage_Run_Skip (0.00s)
=== RUN   TestStepImportImage_Run_Validate
2024/05/17 14:58:41 ui error: error checking required states: missing required state: supervisor_namespace
2024/05/17 14:58:41 ui error: failed to initialize image import: missing required state: supervisor_namespace
2024/05/17 14:58:41 ui error: failed to initialize image import: failed to cast kube_client to type client.WithWatch
2024/05/17 14:58:41 ui: Validating image import request...
2024/05/17 14:58:41 ui error: failed to validate import image configs: import request source url certificate is empty
2024/05/17 14:58:41 ui: Validating image import request...
2024/05/17 14:58:41 ui error: failed to return the content library by name cl-6066c61f7931c5ef9 in namespace test-ns
2024/05/17 14:58:41 ui error: failed to validate import image configs: contentlibraries.imageregistry.vmware.com "cl-6066c61f7931c5ef9" not found
2024/05/17 14:58:41 ui: Validating image import request...
2024/05/17 14:58:41 ui error: failed to validate import image configs: import target content library "cl-6066c61f7931c5ef9" is not writable or does not allow import
2024/05/17 14:58:41 ui: Validating image import request...
2024/05/17 14:58:41 ui error: failed to validate import image configs: image type other is not supported
--- PASS: TestStepImportImage_Run_Validate (0.00s)
=== RUN   TestStepImportImage_Run
2024/05/17 14:58:41 ui: Validating image import request...
2024/05/17 14:58:41 ui: Image import request source and target are valid.
2024/05/17 14:58:41 ui: Importing the source image from https://example.com/example.ovf to cl-6066c61f7931c5ef9.
2024/05/17 14:58:41 ui: Creating ContentLibraryItemImportRequest object test-req-name in namespace test-ns.
2024/05/17 14:58:41 ui: Successfully created the ContentLibraryItemImportRequest object test-req-name.
2024/05/17 14:58:42 ui: Successfully imported the image as a content library item &{"imageregistry.vmware.com/v1alpha1" "ContentLibraryItem" "clitem-xxx"}.
2024/05/17 14:58:42 ui: Finished importing the image from https://example.com/example.ovf to cl-6066c61f7931c5ef9.
--- PASS: TestStepImportImage_Run (1.00s)
=== RUN   TestStepImportImage_Cleanup
2024/05/17 14:58:42 ui: Skipping clean up of the ContentLibraryItemImportRequest object as specified in config.
2024/05/17 14:58:42 ui: Deleting the ContentLibraryItemImportRequest object test-req-name from Supervisor cluster.
2024/05/17 14:58:42 ui: Successfully deleted the ContentLibraryItemImportRequest object.
--- PASS: TestStepImportImage_Cleanup (0.00s)

$ make testacc
all acceptance tests pass except some tests under github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/iso, which doesn't look related to the change.

Supervisor packer build pass with import_source URL: https://wp-content-pstg.broadcom.com/vmimagesvc/ubuntu-jammy-22.04-cloudimg-signed/ubuntu-jammy-22.04-cloudimg-signed.ovf

packer build --var-file tmp/packer-example.json tmp/packer-example.pkr.hcl vsphere-supervisor.vm: 

==> vsphere-supervisor.vm: Creating temporary RSA SSH key for instance...
    vsphere-supervisor.vm: Connecting to Supervisor cluster...
    vsphere-supervisor.vm: Successfully connected to Supervisor cluster
    vsphere-supervisor.vm: Validating VM publish location...
    vsphere-supervisor.vm: VM publish location is valid
    vsphere-supervisor.vm: Validating image import request...
    vsphere-supervisor.vm: Image import request source and target are valid
    vsphere-supervisor.vm: Importing the source image from https://wp-content-pstg.broadcom.com/vmimagesvc/ubuntu-jammy-22.04-cloudimg-signed/ubuntu-jammy-22.04-cloudimg-signed.ovf to cl-6066c61f7931c5ef9
    vsphere-supervisor.vm: Creating a ContentLibraryItemImportRequest object <sensitive>-vsphere-supervisor-import-req-71b5a
    vsphere-supervisor.vm: Successfully created the ContentLibraryItemImportRequest object <sensitive>-vsphere-supervisor-import-req-71b5a
    vsphere-supervisor.vm: Waiting for the image import request to complete...
    vsphere-supervisor.vm: Waiting for the image import request to complete...
    vsphere-supervisor.vm: Successfully imported the image as library item &{"imageregistry.<sensitive>.com/v1alpha1" "ContentLibraryItem" "clitem-c950e9d6dc3b57ee4"}
    vsphere-supervisor.vm: Finished importing the image from https://wp-content-pstg.broadcom.com/vmimagesvc/ubuntu-jammy-22.04-cloudimg-signed/ubuntu-jammy-22.04-cloudimg-signed.ovf to "cl-6066c61f7931c5ef9"
    vsphere-supervisor.vm: Creating required source objects in Supervisor cluster...
    vsphere-supervisor.vm: Creating a K8s Secret object for providing source VM bootstrap data...
    vsphere-supervisor.vm: Using default cloud-init user data as the 'bootstrap_data_file' is not specified
    vsphere-supervisor.vm: Successfully created the K8s Secret object
    vsphere-supervisor.vm: Creating a source VirtualMachine object
    vsphere-supervisor.vm: Successfully created the VirtualMachine object
    vsphere-supervisor.vm: Creating a VirtualMachineService object for network connection
    vsphere-supervisor.vm: Successfully created the VirtualMachineService object
    vsphere-supervisor.vm: Finished creating all required source objects in Supervisor cluster
    vsphere-supervisor.vm: Waiting for the source VM to be powered-on and accessible...
    vsphere-supervisor.vm: Source VM is NOT powered-on yet, continue watching...
    vsphere-supervisor.vm: Source VM is NOT powered-on yet, continue watching...
    vsphere-supervisor.vm: Source VM is powered-on, waiting for an IP to be assigned...
    vsphere-supervisor.vm: Source VM is powered-on, waiting for an IP to be assigned...
    vsphere-supervisor.vm: Successfully obtained the source VM IP: 192.168.128.189
    vsphere-supervisor.vm: Getting source VM ingress IP from the VMService object
    vsphere-supervisor.vm: Successfully retrieved the source VM ingress IP: 192.168.0.4
    vsphere-supervisor.vm: Source VM is now ready in Supervisor cluster
==> vsphere-supervisor.vm: Using SSH communicator to connect: 192.168.0.4 ==> vsphere-supervisor.vm: Waiting for SSH to become available... ==> vsphere-supervisor.vm: Connected to SSH!
==> vsphere-supervisor.vm: Provisioning with shell script: /var/folders/gc/ptc0zb0507b05r97rqnb5cym0000gq/T/<sensitive>-shell1862650776
    vsphere-supervisor.vm: Publishing the source VM to "cl-6066c61f7931c5ef9"
    vsphere-supervisor.vm: Creating a VirtualMachinePublishRequest object
    vsphere-supervisor.vm: Successfully created the VirtualMachinePublishRequest object
    vsphere-supervisor.vm: Waiting for the VM publish request to complete...
    vsphere-supervisor.vm: Waiting for the VM publish request to complete...
    vsphere-supervisor.vm: Successfully published the VM to image "vmi-2569621448a150e8a"
    vsphere-supervisor.vm: Finished publishing the source VM
    vsphere-supervisor.vm: Deleting the VirtualMachinePublishRequest object from Supervisor cluster
    vsphere-supervisor.vm: Successfully deleted the VirtualMachinePublishRequest object
    vsphere-supervisor.vm: Deleting the imported ContentLibraryItem object clitem-19fab321189b7b177 in namespace test-k8s-service.
    vsphere-supervisor.vm: Successfully deleted the ContentLibraryItem object clitem-19fab321189b7b177 in namespace test-k8s-service.
    vsphere-supervisor.vm: Deleting the VirtualMachineService object from Supervisor cluster
    vsphere-supervisor.vm: Successfully deleted the VirtualMachineService object
    vsphere-supervisor.vm: Deleting the VirtualMachine object from Supervisor cluster
    vsphere-supervisor.vm: Successfully deleted the VirtualMachine object
    vsphere-supervisor.vm: Deleting the K8s Secret object from Supervisor cluster
    vsphere-supervisor.vm: Successfully deleted the K8s Secret object
    vsphere-supervisor.vm: Deleting the ContentLibraryItemImportRequest object <sensitive>-vsphere-supervisor-import-req-71b5a from Supervisor cluster
    vsphere-supervisor.vm: Successfully deleted the ContentLibraryItemImportRequest object
    vsphere-supervisor.vm: Build 'vsphere-supervisor' finished successfully.
Build 'vsphere-supervisor.vm' finished after 5 minutes 3 seconds.

Supervisor packer build pass without setting import_source_url (use existing image instead)

Reference

Closes #434

hashicorp-cla-app[bot] commented 1 month ago

CLA assistant check
All committers have signed the CLA.

ericvmw commented 1 month ago

Thanks, Eric!

  • Per the README.md, in case of feature contribution, we kindly ask you to open an issue to discuss it beforehand so that these can be linked.
  • Could you use the Conventional Commits style and ensure it is signed off with your broadcom.com email attached to your GitHub account. The commit message should be short and you can leave this content in the linked PR.
  • Also, please update https://github.com/hashicorp/packer-plugin-vsphere/blob/main/docs/builders/vsphere-supervisor.mdx to include the new items as this will then populate webdocs when make generate is run.

Thanks Ryan! Updated as below:

  1. Opened the issue here: https://github.com/hashicorp/packer-plugin-vsphere/issues/434.
  2. Shortened the commit message and included my broadcom.com email.
  3. Updated the vsphere-supervisor.mdx, regenerated the webdocs, and fixed lint issues.
ericvmw commented 1 month ago

Just one more minor nit from staticcheck and marking all conversations as closed.

Looks good, Eric. 🎉

Updated that one too, and some refactoring per Sai's suggestions, please review again when you get a chance, thanks Ryan!

ericvmw commented 1 month ago

Minor items.

Thanks for the review, addressed the comments, please take a look again.

ericvmw commented 1 month ago

LGTM! Thansk for your patience @ericvmw and many thanks to @dilyar85 for your reviews as well.

Thanks @tenthirtyam @dilyar85 for the thorough reviews, truly appreciate it!

nywilken commented 3 weeks ago

I manually resolved the conflicts and pushed. Once green I will merge.

nywilken commented 2 weeks ago

Hi @ericvmw thank you for addressing the few pieces of feedback. I will merge this today and release the plugin this week. If @tenthirtyam has no objections.