Skip to content

Commit

Permalink
get org and proj id from client secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
sylviamoss committed Jul 27, 2021
1 parent 765715f commit 9943301
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 91 deletions.
57 changes: 15 additions & 42 deletions internal/packer_registry/client.go
Original file line number Diff line number Diff line change
@@ -1,66 +1,38 @@
package packer_registry

import (
"errors"

packerSvc "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/preview/2021-04-30/client/packer_service"
"github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/client/organization_service"
"github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/client/project_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"
"github.com/hashicorp/hcp-sdk-go/httpclient"
)

// ClientConfig specifies configuration for the client that interacts with HCP
type ClientConfig struct {
ClientID string
ClientSecret string

// OrganizationID is the organization unique identifier on HCP.
OrganizationID string

// ProjectID is the project unique identifier on HCP.
ProjectID string
}

func (cfg ClientConfig) Validate() error {
if cfg.OrganizationID == "" {
return &ClientError{
StatusCode: InvalidClientConfig,
Err: errors.New(`no valid HCP Organization ID found, check that HCP_PACKER_REGISTRY is in the format "HCP_ORG_ID/HCP_PROJ_ID"`),
}

}

if cfg.ProjectID == "" {
return &ClientError{
StatusCode: InvalidClientConfig,
Err: errors.New(`no valid HCP Project ID found, check that HCP_PACKER_REGISTRY is in the format "HCP_ORG_ID/HCP_PROJ_ID"`),
}
}

return nil
}

// Client is an HCP client capable of making requests on behalf of a service principal
type Client struct {
Config ClientConfig

Organization organization_service.ClientService
Project project_service.ClientService
Organization organizationSvc.ClientService
Project projectSvc.ClientService
Packer packerSvc.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, HCP_CLIENT_SECRET, and HCP_PACKER_REGISTRY.
// if not explicitly provided via a valid ClientConfig cfg.
// Upon error a HCPClientError will be returned.
func NewClient(cfg ClientConfig) (*Client, error) {
if err := cfg.Validate(); err != nil {
return nil, &ClientError{
StatusCode: InvalidClientConfig,
Err: err,
}
}

cl, err := httpclient.New(httpclient.Config{})
if err != nil {
return nil, &ClientError{
Expand All @@ -69,10 +41,11 @@ func NewClient(cfg ClientConfig) (*Client, error) {
}
}

svc := packerSvc.New(cl, nil)
return &Client{
Packer: svc,
Config: cfg,
Packer: packerSvc.New(cl, nil),
Organization: organizationSvc.New(cl, nil),
Project: projectSvc.New(cl, nil),
Config: cfg,
}, nil

}

6 changes: 0 additions & 6 deletions internal/packer_registry/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ func HasClientSecret() bool {
return ok
}

func HasPackerRegistryDestionation() bool {
_, ok := os.LookupEnv(HCPPackerRegistry)
return ok
}

func HasPackerRegistryBucket() bool {
_, ok := os.LookupEnv(HCPPackerBucket)
return ok
Expand All @@ -26,7 +21,6 @@ func InPARMode() bool {
checks := []func() bool{
HasClientID,
HasClientSecret,
HasPackerRegistryDestionation,
}

for _, check := range checks {
Expand Down
7 changes: 3 additions & 4 deletions internal/packer_registry/env/variables.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package env

const (
HCPClientID = "HCP_CLIENT_ID"
HCPClientSecret = "HCP_CLIENT_SECRET"
HCPPackerRegistry = "HCP_PACKER_REGISTRY"
HCPPackerBucket = "HCP_PACKER_BUCKET_NAME"
HCPClientID = "HCP_CLIENT_ID"
HCPClientSecret = "HCP_CLIENT_SECRET"
HCPPackerBucket = "HCP_PACKER_BUCKET_NAME"
)
28 changes: 14 additions & 14 deletions internal/packer_registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
func CreateBucket(ctx context.Context, client *Client, input *models.HashicorpCloudPackerCreateBucketRequest) (string, error) {

params := packerSvc.NewCreateBucketParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.Body = input

resp, err := client.Packer.CreateBucket(params, nil, func(*runtime.ClientOperation) {})
Expand All @@ -41,8 +41,8 @@ func UpsertBucket(ctx context.Context, client *Client, input *models.HashicorpCl
}

params := packerSvc.NewUpdateBucketParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.BucketSlug = input.BucketSlug
params.Body = &models.HashicorpCloudPackerUpdateBucketRequest{
Description: input.Description,
Expand All @@ -62,8 +62,8 @@ input: *models.HashicorpCloudPackerCreateIterationRequest{BucketSlug: "bucket na
func CreateIteration(ctx context.Context, client *Client, input *models.HashicorpCloudPackerCreateIterationRequest) (string, error) {
// Create/find iteration
params := packerSvc.NewCreateIterationParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.BucketSlug = input.BucketSlug
params.Body = input

Expand All @@ -78,8 +78,8 @@ func CreateIteration(ctx context.Context, client *Client, input *models.Hashicor
func GetIteration(ctx context.Context, client *Client, bucketslug string, fingerprint string) (string, error) {
// Create/find iteration
params := packerSvc.NewGetIterationParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.BucketSlug = bucketslug
// identifier can be either fingerprint, iterationid, or incremental version
// for now, we only care about fingerprint so we're hardcoding it.
Expand All @@ -95,8 +95,8 @@ func GetIteration(ctx context.Context, client *Client, bucketslug string, finger

func CreateBuild(ctx context.Context, client *Client, input *models.HashicorpCloudPackerCreateBuildRequest) (string, error) {
params := packerSvc.NewCreateBuildParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.BucketSlug = input.BucketSlug
params.BuildIterationID = input.Build.IterationID
params.Body = input
Expand All @@ -111,8 +111,8 @@ func CreateBuild(ctx context.Context, client *Client, input *models.HashicorpClo

func ListBuilds(ctx context.Context, client *Client, bucketSlug string, iterationID string) ([]*models.HashicorpCloudPackerBuild, error) {
params := packerSvc.NewListBuildsParamsWithContext(ctx)
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.BucketSlug = bucketSlug
params.IterationID = iterationID

Expand All @@ -127,8 +127,8 @@ func ListBuilds(ctx context.Context, client *Client, bucketSlug string, iteratio
func UpdateBuild(ctx context.Context, client *Client, input *models.HashicorpCloudPackerUpdateBuildRequest) (string, error) {
params := packerSvc.NewUpdateBuildParamsWithContext(ctx)
params.BuildID = input.BuildID
params.LocationOrganizationID = client.Config.OrganizationID
params.LocationProjectID = client.Config.ProjectID
params.LocationOrganizationID = client.OrganizationID
params.LocationProjectID = client.ProjectID
params.Body = input

resp, err := client.Packer.UpdateBuild(params, nil, func(*runtime.ClientOperation) {})
Expand Down
69 changes: 44 additions & 25 deletions internal/packer_registry/types.bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"fmt"
"log"
"os"
"strings"
"sync"

"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/preview/2021-04-30/models"
"github.com/hashicorp/hcp-sdk-go/clients/cloud-resource-manager/preview/2019-12-10/client/organization_service"
"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/packer/internal/packer_registry/env"
"google.golang.org/grpc/codes"
)
Expand Down Expand Up @@ -48,10 +50,6 @@ func (b *Bucket) Validate() error {
return fmt.Errorf("no Packer bucket name defined; either the environment variable %q is undefined or the HCL configuration has no build name", env.HCPPackerBucket)
}

if b.Destination == "" {
return fmt.Errorf("no Packer registry defined; either the environment variable %q is undefined or the HCL configuration has no build name", env.HCPPackerRegistry)
}

return nil
}

Expand All @@ -69,6 +67,15 @@ func (b *Bucket) Initialize(ctx context.Context) error {
}
}

if err := b.loadOrganizationIDFromCredentials(); err != nil {
return err
}
if err := b.loadProjectIDFromCredentials(); err != nil {
return err
}

b.Destination = fmt.Sprintf("%s/%s", b.client.OrganizationID, b.client.ProjectID)

bucketInput := &models.HashicorpCloudPackerCreateBucketRequest{
BucketSlug: b.Slug,
Description: b.Description,
Expand Down Expand Up @@ -177,6 +184,38 @@ func (b *Bucket) Initialize(ctx context.Context) error {
return errs.ErrorOrNil()
}

func (b *Bucket) loadOrganizationIDFromCredentials() error {
// Get the organization ID.
listOrgParams := organization_service.NewOrganizationServiceListParams()
listOrgResp, err := b.client.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)
}
b.client.OrganizationID = listOrgResp.Payload.Organizations[0].ID
return nil
}

func (b *Bucket) loadProjectIDFromCredentials() error {
// Get the project using the organization ID.
listProjParams := project_service.NewProjectServiceListParams()
listProjParams.ScopeID = &b.client.OrganizationID
scopeType := string(rmmodels.HashicorpCloudResourcemanagerResourceIDResourceTypeORGANIZATION)
listProjParams.ScopeType = &scopeType
listProjResp, err := b.client.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, upgrade to a later provider version and set a project ID on the provider/resources")
}
b.client.ProjectID = listProjResp.Payload.Projects[0].ID
return nil
}

// connect initializes a client connection to a remote HCP Packer Registry service on HCP.
// Upon a successful connection the initialized client is persisted on the Bucket b for later usage.
func (b *Bucket) connect() error {
Expand Down Expand Up @@ -344,26 +383,6 @@ func (b *Bucket) LoadDefaultSettingsFromEnv() {
b.Slug = os.Getenv(env.HCPPackerBucket)
}

loc := os.Getenv(env.HCPPackerRegistry)
locParts := strings.Split(loc, "/")
if len(locParts) != 2 {
// we want an error here. Or at least when we try to create the registry client we fail
return
}
orgID, projID := locParts[0], locParts[1]

if b.Destination == "" {
b.Destination = loc
}

if b.Config.OrganizationID == "" {
b.Config.OrganizationID = orgID
}

if b.Config.ProjectID == "" {
b.Config.ProjectID = projID
}

// Set some iteration values. For Packer RunUUID should always be set.
// Creating a bucket differently? Let's not overwrite a UUID that might be set.
if b.Iteration.RunUUID == "" {
Expand Down

0 comments on commit 9943301

Please sign in to comment.