You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
packer/internal/hcp/env/env.go

127 lines
3.6 KiB

// Copyright IBM Corp. 2013, 2025
// SPDX-License-Identifier: BUSL-1.1
// Package env provides HCP Packer environment variables.
package env
import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
"strings"
)
func HasHCPAuth() (bool, error) {
// Client crendential authentication requires the following environment variables be set; `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET`.
hasClientCredentials := HasHCPClientCredentials()
// Client certificate authentication requires a valid HCP certificate file placed in either the default location (~/.config/hcp/cred_file.json) or at a location specified in the `HCP_CRED_FILE` env var
hasCertificate, err := HasHCPCertificateFile()
if err != nil {
return false, err
}
if hasClientCredentials && hasCertificate {
fmt.Printf("HCP Client Credentials (HCP_CLIENT_ID/HCP_CLIENT_SECRET environment variables) and certificate (HCP_CRED_FILE environment variable, or certificate located at default path (%s) are both supplied, only one is required. The HCP SDK will determine which authentication mechanism to configure here, it is reccomended to only configure one authentication method", HCPDefaultCredFilePathFull)
}
return (hasClientCredentials || hasCertificate), nil
}
func HasProjectID() bool {
return hasEnvVar(HCPProjectID)
}
func HasOrganizationID() bool {
return hasEnvVar(HCPOrganizationID)
}
func HasClientID() bool {
return hasEnvVar(HCPClientID)
}
func HasClientSecret() bool {
return hasEnvVar(HCPClientSecret)
}
func HasPackerRegistryBucket() bool {
return hasEnvVar(HCPPackerBucket)
}
func hasEnvVar(varName string) bool {
val, ok := os.LookupEnv(varName)
if !ok {
return false
}
return val != ""
}
func HasHCPClientCredentials() bool {
checks := []func() bool{
HasClientID,
HasClientSecret,
}
for _, check := range checks {
if !check() {
return false
}
}
return true
}
func HasHCPCertificateFile() (bool, error) {
envVarCredFile, _ := os.LookupEnv(HCPCredFile)
var envVarCertExists bool
var err error
if envVarCredFile != "" {
envVarCertExists, err = fileExists(envVarCredFile)
if err != nil {
return false, err
}
}
// Get the user's home directory.
userHome, err := os.UserHomeDir()
if err != nil {
return false, fmt.Errorf("failed to retrieve user's home directory path: %v", err)
}
// builds file path ~/.config/hcp/cred_file.json, if we don't parse the home directory os.Stat can't find the default credential path
defaultCredFilePath := filepath.Join(userHome, HCPDefaultCredFilePath, HCPDefaultCredFile)
log.Printf("Checking for default HCP credential file at path %s", defaultCredFilePath)
defaultPathCertExists, err := fileExists(defaultCredFilePath)
if err != nil {
return false, err
}
log.Printf("Default file found status - %t", defaultPathCertExists)
if envVarCertExists && defaultPathCertExists {
fmt.Println("A HCP credential file was found at the default path, and an HCP_CRED_FILE was specified, the HCP SDK will use the HCP_CRED_FILE")
}
if envVarCertExists || defaultPathCertExists {
return true, nil
}
return false, nil
}
func IsHCPDisabled() bool {
hcp, ok := os.LookupEnv(HCPPackerRegistry)
return ok && strings.ToLower(hcp) == "off" || hcp == "0"
}
// IsHCPExplicitelyEnabled returns true if the client enabled HCP_PACKER_REGISTRY explicitely, i.e. it is defined and not 0 or off
func IsHCPExplicitelyEnabled() bool {
_, ok := os.LookupEnv(HCPPackerRegistry)
return ok && !IsHCPDisabled()
}
func fileExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil // Path exists, no error
}
if errors.Is(err, os.ErrNotExist) {
return false, nil // Path does not exist
}
return false, err // Another error occurred
}