mirror of
https://github.com/hashicorp/packer.git
synced 2026-04-28 09:39:58 -04:00
101 lines
3.4 KiB
Go
101 lines
3.4 KiB
Go
package registry
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
packerSvc "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/stable/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"
|
|
"github.com/hashicorp/packer/version"
|
|
)
|
|
|
|
// 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{
|
|
SourceChannel: fmt.Sprintf("packer/%s", version.PackerVersion.FormattedVersion()),
|
|
})
|
|
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
|
|
}
|