Files
Packer-Cn/internal/registry/client.go
T
Wilken Rivera b10df3abb7 Update HCP Packer registry image extraction, validation, publishing logic for registry capable plugins (#11221)
* Update handling of registry artifacts

This change uses the github.com/hashicorp/packer-plgin-sdk/packer/registryimage for querying
Artifact State for HCP Registry Image metadata. To handle the conversion
of the RPC response, mapstructure was introduced to conversion state
data into an registryimage.Image before publishing to a image bucket.

* Update to use registry image from packersdk

* Rename internal registry service pkg

* Update vendored plugins to latest version

* The latest release of Amazon, GoogleCompute, and Azure have support
  for publishing images to the HCP Packer registry.
2021-09-13 21:07:54 -04:00

99 lines
3.3 KiB
Go

package registry
import (
"fmt"
packerSvc "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/preview/2021-04-30/client/packer_service"
organizationSvc "github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/client/organization_service"
projectSvc "github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/client/project_service"
rmmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/models"
"github.com/hashicorp/hcp-sdk-go/httpclient"
"github.com/hashicorp/packer/internal/registry/env"
)
// Client is an HCP client capable of making requests on behalf of a service principal
type Client struct {
Packer packerSvc.ClientService
Organization organizationSvc.ClientService
Project projectSvc.ClientService
// OrganizationID is the organization unique identifier on HCP.
OrganizationID string
// ProjectID is the project unique identifier on HCP.
ProjectID string
}
// NewClient returns an authenticated client to a HCP Packer Registry.
// Client authentication requires the following environment variables be set HCP_CLIENT_ID and HCP_CLIENT_SECRET.
// Upon error a HCPClientError will be returned.
func NewClient() (*Client, error) {
if !env.HasHCPCredentials() {
return nil, &ClientError{
StatusCode: InvalidClientConfig,
Err: fmt.Errorf("the client authentication requires both %s and %s environment variables to be set", env.HCPClientID, env.HCPClientSecret),
}
}
cl, err := httpclient.New(httpclient.Config{})
if err != nil {
return nil, &ClientError{
StatusCode: InvalidClientConfig,
Err: err,
}
}
client := &Client{
Packer: packerSvc.New(cl, nil),
Organization: organizationSvc.New(cl, nil),
Project: projectSvc.New(cl, nil),
}
if err := client.loadOrganizationID(); err != nil {
return nil, &ClientError{
StatusCode: InvalidClientConfig,
Err: err,
}
}
if err := client.loadProjectID(); err != nil {
return nil, &ClientError{
StatusCode: InvalidClientConfig,
Err: err,
}
}
return client, nil
}
func (c *Client) loadOrganizationID() error {
// Get the organization ID.
listOrgParams := organizationSvc.NewOrganizationServiceListParams()
listOrgResp, err := c.Organization.OrganizationServiceList(listOrgParams, nil)
if err != nil {
return fmt.Errorf("unable to fetch organization list: %v", err)
}
orgLen := len(listOrgResp.Payload.Organizations)
if orgLen != 1 {
return fmt.Errorf("unexpected number of organizations: expected 1, actual: %v", orgLen)
}
c.OrganizationID = listOrgResp.Payload.Organizations[0].ID
return nil
}
func (c *Client) loadProjectID() error {
// Get the project using the organization ID.
listProjParams := projectSvc.NewProjectServiceListParams()
listProjParams.ScopeID = &c.OrganizationID
scopeType := string(rmmodels.HashicorpCloudResourcemanagerResourceIDResourceTypeORGANIZATION)
listProjParams.ScopeType = &scopeType
listProjResp, err := c.Project.ProjectServiceList(listProjParams, nil)
if err != nil {
return fmt.Errorf("unable to fetch project id: %v", err)
}
if len(listProjResp.Payload.Projects) > 1 {
return fmt.Errorf("this version of Packer does not support multiple projects")
}
c.ProjectID = listProjResp.Payload.Projects[0].ID
return nil
}