rebase the branch
This commit is contained in:
parent
be56632f7e
commit
f13099edfb
|
@ -14,31 +14,32 @@ type ServiceAccount struct {
|
|||
jwt *jwt.Config
|
||||
}
|
||||
|
||||
// ProcessAccountFile will return a ServiceAccount for the JSON account file stored in text.
|
||||
// Otherwise it will return an error if text does not look or reference a valid account file.
|
||||
func ProcessAccountFile(text string) (*ServiceAccount, error) {
|
||||
// Assume text is a JSON string
|
||||
// This func is used for validation now to avoid causing errors in NewClientGCE function
|
||||
var err error
|
||||
var data []byte
|
||||
conf, err := google.JWTConfigFromJSON([]byte(text), DriverScopes...)
|
||||
if err != nil {
|
||||
if conf, err := google.JWTConfigFromJSON([]byte(text), DriverScopes...); err == nil {
|
||||
return &ServiceAccount{
|
||||
jsonKey: []byte(text),
|
||||
jwt: conf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// If text was not JSON, assume it is a file path instead
|
||||
if _, err = os.Stat(text); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf(
|
||||
"account_file path does not exist: %s",
|
||||
text)
|
||||
if _, err := os.Stat(text); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("account_file path does not exist: %s", text)
|
||||
}
|
||||
data, err = ioutil.ReadFile(text)
|
||||
|
||||
data, err := ioutil.ReadFile(text)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Error reading account_file from path '%s': %s",
|
||||
text, err)
|
||||
return nil, fmt.Errorf("Error reading account_file from path '%s': %s", text, err)
|
||||
}
|
||||
conf, err = google.JWTConfigFromJSON(data, DriverScopes...)
|
||||
|
||||
conf, err := google.JWTConfigFromJSON(data, DriverScopes...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing account_file: %s", err)
|
||||
}
|
||||
}
|
||||
data = []byte(text)
|
||||
|
||||
return &ServiceAccount{
|
||||
jsonKey: data,
|
||||
jwt: conf,
|
||||
|
|
|
@ -36,8 +36,15 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
|||
// Run executes a googlecompute Packer build and returns a packer.Artifact
|
||||
// representing a GCE machine image.
|
||||
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||
driver, err := NewDriverGCE(
|
||||
ui, b.config.ProjectId, b.config.account, b.config.VaultGCPOauthEngine, b.config.ImpersonatedServiceAccount)
|
||||
cfg := GCEDriverConfig{
|
||||
Ui: ui,
|
||||
ProjectId: b.config.ProjectId,
|
||||
Account: b.config.account,
|
||||
ImpersonateServiceAccountName: b.config.ImpersonateServiceAccount,
|
||||
VaultOauthEngineName: b.config.VaultGCPOauthEngine,
|
||||
}
|
||||
|
||||
driver, err := NewDriverGCE(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ type Config struct {
|
|||
// run Packer on a GCE instance with a service account. Instructions for
|
||||
// creating the file or using service accounts are above.
|
||||
AccountFile string `mapstructure:"account_file" required:"false"`
|
||||
// This allows service account impersonation as per the docs.
|
||||
ImpersonatedServiceAccount string `mapstructure:"impersonated_service_account" required:"false"`
|
||||
// This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
ImpersonateServiceAccount string `mapstructure:"impersonate_service_account" required:"false"`
|
||||
// The project ID that will be used to launch instances and store images.
|
||||
ProjectId string `mapstructure:"project_id" required:"true"`
|
||||
// Full or partial URL of the guest accelerator type. GPU accelerators can
|
||||
|
@ -482,9 +482,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
|||
|
||||
// Authenticating via an account file
|
||||
if c.AccountFile != "" {
|
||||
if c.VaultGCPOauthEngine != "" && c.ImpersonatedServiceAccount != "" {
|
||||
if c.VaultGCPOauthEngine != "" && c.ImpersonateServiceAccount != "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("You cannot "+
|
||||
"specify impersonated_service_account, account_file and vault_gcp_oauth_engine at the same time"))
|
||||
"specify impersonate_service_account, account_file and vault_gcp_oauth_engine at the same time"))
|
||||
}
|
||||
cfg, err := ProcessAccountFile(c.AccountFile)
|
||||
if err != nil {
|
||||
|
|
|
@ -64,7 +64,7 @@ type FlatConfig struct {
|
|||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"`
|
||||
AccountFile *string `mapstructure:"account_file" required:"false" cty:"account_file" hcl:"account_file"`
|
||||
ImpersonatedServiceAccount *string `mapstructure:"impersonated_service_account" required:"false" cty:"impersonated_service_account" hcl:"impersonated_service_account"`
|
||||
ImpersonateServiceAccount *string `mapstructure:"impersonate_service_account" required:"false" cty:"impersonate_service_account" hcl:"impersonate_service_account"`
|
||||
ProjectId *string `mapstructure:"project_id" required:"true" cty:"project_id" hcl:"project_id"`
|
||||
AcceleratorType *string `mapstructure:"accelerator_type" required:"false" cty:"accelerator_type" hcl:"accelerator_type"`
|
||||
AcceleratorCount *int64 `mapstructure:"accelerator_count" required:"false" cty:"accelerator_count" hcl:"accelerator_count"`
|
||||
|
@ -183,7 +183,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"account_file": &hcldec.AttrSpec{Name: "account_file", Type: cty.String, Required: false},
|
||||
"impersonated_service_account": &hcldec.AttrSpec{Name: "impersonated_service_account", Type: cty.String, Required: false},
|
||||
"impersonate_service_account": &hcldec.AttrSpec{Name: "impersonate_service_account", Type: cty.String, Required: false},
|
||||
"project_id": &hcldec.AttrSpec{Name: "project_id", Type: cty.String, Required: false},
|
||||
"accelerator_type": &hcldec.AttrSpec{Name: "accelerator_type", Type: cty.String, Required: false},
|
||||
"accelerator_count": &hcldec.AttrSpec{Name: "accelerator_count", Type: cty.Number, Required: false},
|
||||
|
|
|
@ -35,6 +35,14 @@ type driverGCE struct {
|
|||
ui packer.Ui
|
||||
}
|
||||
|
||||
type GCEDriverConfig struct {
|
||||
Ui packer.Ui
|
||||
ProjectId string
|
||||
Account *ServiceAccount
|
||||
ImpersonateServiceAccountName string
|
||||
VaultOauthEngineName string
|
||||
}
|
||||
|
||||
var DriverScopes = []string{"https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control"}
|
||||
|
||||
// Define a TokenSource that gets tokens from Vault
|
||||
|
@ -70,7 +78,7 @@ func (ots OauthTokenSource) Token() (*oauth2.Token, error) {
|
|||
|
||||
}
|
||||
|
||||
func NewClientGCE(account *ServiceAccount, vaultOauth string, impersonatedsa string) (option.ClientOption, error) {
|
||||
func NewClientOptionGoogle(account *ServiceAccount, vaultOauth string, impersonatesa string) (option.ClientOption, error) {
|
||||
var err error
|
||||
|
||||
var opts option.ClientOption
|
||||
|
@ -81,9 +89,9 @@ func NewClientGCE(account *ServiceAccount, vaultOauth string, impersonatedsa str
|
|||
ts := OauthTokenSource{vaultOauth}
|
||||
opts = option.WithTokenSource(ts)
|
||||
|
||||
} else if impersonatedsa != "" {
|
||||
opts = option.ImpersonateCredentials(impersonatedsa)
|
||||
} else if account.jwt != nil && len(account.jwt.PrivateKey) > 0 {
|
||||
} else if impersonatesa != "" {
|
||||
opts = option.ImpersonateCredentials(impersonatesa)
|
||||
} else if account != nil && account.jwt != nil && len(account.jwt.PrivateKey) > 0 {
|
||||
// Auth with AccountFile if provided
|
||||
log.Printf("[INFO] Requesting Google token via account_file...")
|
||||
log.Printf("[INFO] -- Email: %s", account.jwt.Email)
|
||||
|
@ -119,8 +127,8 @@ func NewClientGCE(account *ServiceAccount, vaultOauth string, impersonatedsa str
|
|||
return opts, nil
|
||||
}
|
||||
|
||||
func NewDriverGCE(ui packer.Ui, p string, account *ServiceAccount, impersonatedsa string, vaultOauth string) (Driver, error) {
|
||||
opts, err := NewClientGCE(account, vaultOauth, impersonatedsa)
|
||||
func NewDriverGCE(config GCEDriverConfig) (Driver, error) {
|
||||
opts, err := NewClientOptionGoogle(config.Account, config.VaultOauthEngineName, config.ImpersonateServiceAccountName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -141,10 +149,10 @@ func NewDriverGCE(ui packer.Ui, p string, account *ServiceAccount, impersonateds
|
|||
service.UserAgent = useragent.String()
|
||||
|
||||
return &driverGCE{
|
||||
projectId: p,
|
||||
projectId: config.ProjectId,
|
||||
service: service,
|
||||
osLoginService: osLoginService,
|
||||
ui: ui,
|
||||
ui: config.Ui,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ type Config struct {
|
|||
//The JSON file containing your account credentials.
|
||||
//If specified, the account file will take precedence over any `googlecompute` builder authentication method.
|
||||
AccountFile string `mapstructure:"account_file"`
|
||||
// This allows service account impersonation as per the docs.
|
||||
ImpersonatedServiceAccount string `mapstructure:"impersonated_service_account" required:"false"`
|
||||
// This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
ImpersonateServiceAccount string `mapstructure:"impersonate_service_account" required:"false"`
|
||||
//The size of the export instances disk.
|
||||
//The disk is unused for the export but a larger size will increase `pd-ssd` read speed.
|
||||
//This defaults to `200`, which is 200GB.
|
||||
|
@ -185,9 +185,15 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
|||
if p.config.ServiceAccountEmail != "" {
|
||||
exporterConfig.ServiceAccountEmail = p.config.ServiceAccountEmail
|
||||
}
|
||||
cfg := googlecompute.GCEDriverConfig{
|
||||
Ui: ui,
|
||||
ProjectId: builderProjectId,
|
||||
Account: p.config.account,
|
||||
ImpersonateServiceAccountName: p.config.ImpersonateServiceAccount,
|
||||
VaultOauthEngineName: p.config.VaultGCPOauthEngine,
|
||||
}
|
||||
|
||||
driver, err := googlecompute.NewDriverGCE(ui, builderProjectId,
|
||||
p.config.account, p.config.VaultGCPOauthEngine, p.config.ImpersonatedServiceAccount)
|
||||
driver, err := googlecompute.NewDriverGCE(cfg)
|
||||
if err != nil {
|
||||
return nil, false, false, err
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ type FlatConfig struct {
|
|||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
|
||||
AccountFile *string `mapstructure:"account_file" cty:"account_file" hcl:"account_file"`
|
||||
ImpersonatedServiceAccount *string `mapstructure:"impersonated_service_account" required:"false" cty:"impersonated_service_account" hcl:"impersonated_service_account"`
|
||||
ImpersonateServiceAccount *string `mapstructure:"impersonate_service_account" required:"false" cty:"impersonate_service_account" hcl:"impersonate_service_account"`
|
||||
DiskSizeGb *int64 `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"`
|
||||
DiskType *string `mapstructure:"disk_type" cty:"disk_type" hcl:"disk_type"`
|
||||
MachineType *string `mapstructure:"machine_type" cty:"machine_type" hcl:"machine_type"`
|
||||
|
@ -49,7 +49,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"account_file": &hcldec.AttrSpec{Name: "account_file", Type: cty.String, Required: false},
|
||||
"impersonated_service_account": &hcldec.AttrSpec{Name: "impersonated_service_account", Type: cty.String, Required: false},
|
||||
"impersonate_service_account": &hcldec.AttrSpec{Name: "impersonate_service_account", Type: cty.String, Required: false},
|
||||
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false},
|
||||
"disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false},
|
||||
"machine_type": &hcldec.AttrSpec{Name: "machine_type", Type: cty.String, Required: false},
|
||||
|
|
|
@ -30,8 +30,8 @@ type Config struct {
|
|||
//The JSON file containing your account credentials.
|
||||
//If specified, the account file will take precedence over any `googlecompute` builder authentication method.
|
||||
AccountFile string `mapstructure:"account_file" required:"true"`
|
||||
// This allows service account impersonation as per the docs.
|
||||
ImpersonatedServiceAccount string `mapstructure:"impersonated_service_account" required:"false"`
|
||||
// This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
ImpersonateServiceAccount string `mapstructure:"impersonate_service_account" required:"false"`
|
||||
//The project ID where the GCS bucket exists and where the GCE image is stored.
|
||||
ProjectId string `mapstructure:"project_id" required:"true"`
|
||||
IAP bool `mapstructure-to-hcl:",skip"`
|
||||
|
@ -100,9 +100,9 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
}
|
||||
|
||||
if p.config.AccountFile != "" {
|
||||
if p.config.VaultGCPOauthEngine != "" && p.config.ImpersonatedServiceAccount != "" {
|
||||
if p.config.VaultGCPOauthEngine != "" && p.config.ImpersonateServiceAccount != "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("You cannot "+
|
||||
"specify impersonated_service_account, account_file and vault_gcp_oauth_engine at the same time"))
|
||||
"specify impersonate_service_account, account_file and vault_gcp_oauth_engine at the same time"))
|
||||
}
|
||||
cfg, err := googlecompute.ProcessAccountFile(p.config.AccountFile)
|
||||
if err != nil {
|
||||
|
@ -139,7 +139,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
|||
p.config.ctx.Data = generatedData
|
||||
var err error
|
||||
var opts option.ClientOption
|
||||
opts, err = googlecompute.NewClientGCE(p.config.account, p.config.VaultGCPOauthEngine, p.config.ImpersonatedServiceAccount)
|
||||
opts, err = googlecompute.NewClientOptionGoogle(p.config.account, p.config.VaultGCPOauthEngine, p.config.ImpersonateServiceAccount)
|
||||
if err != nil {
|
||||
return nil, false, false, err
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ type FlatConfig struct {
|
|||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
|
||||
AccountFile *string `mapstructure:"account_file" required:"true" cty:"account_file" hcl:"account_file"`
|
||||
ImpersonatedServiceAccount *string `mapstructure:"impersonated_service_account" required:"false" cty:"impersonated_service_account" hcl:"impersonated_service_account"`
|
||||
ImpersonateServiceAccount *string `mapstructure:"impersonate_service_account" required:"false" cty:"impersonate_service_account" hcl:"impersonate_service_account"`
|
||||
ProjectId *string `mapstructure:"project_id" required:"true" cty:"project_id" hcl:"project_id"`
|
||||
IAP *bool `mapstructure-to-hcl:",skip" cty:"iap" hcl:"iap"`
|
||||
Bucket *string `mapstructure:"bucket" required:"true" cty:"bucket" hcl:"bucket"`
|
||||
|
@ -51,7 +51,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"account_file": &hcldec.AttrSpec{Name: "account_file", Type: cty.String, Required: false},
|
||||
"impersonated_service_account": &hcldec.AttrSpec{Name: "impersonated_service_account", Type: cty.String, Required: false},
|
||||
"impersonate_service_account": &hcldec.AttrSpec{Name: "impersonate_service_account", Type: cty.String, Required: false},
|
||||
"project_id": &hcldec.AttrSpec{Name: "project_id", Type: cty.String, Required: false},
|
||||
"iap": &hcldec.AttrSpec{Name: "iap", Type: cty.Bool, Required: false},
|
||||
"bucket": &hcldec.AttrSpec{Name: "bucket", Type: cty.String, Required: false},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
run Packer on a GCE instance with a service account. Instructions for
|
||||
creating the file or using service accounts are above.
|
||||
|
||||
- `impersonated_service_account` (string) - This allows service account impersonation as per the docs.
|
||||
- `impersonate_service_account` (string) - This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
|
||||
- `accelerator_type` (string) - Full or partial URL of the guest accelerator type. GPU accelerators can
|
||||
only be used with `"on_host_maintenance": "TERMINATE"` option set.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- `account_file` (string) - The JSON file containing your account credentials.
|
||||
If specified, the account file will take precedence over any `googlecompute` builder authentication method.
|
||||
|
||||
- `impersonated_service_account` (string) - This allows service account impersonation as per the docs.
|
||||
- `impersonate_service_account` (string) - This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
|
||||
- `disk_size` (int64) - The size of the export instances disk.
|
||||
The disk is unused for the export but a larger size will increase `pd-ssd` read speed.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!-- Code generated from the comments of the Config struct in post-processor/googlecompute-import/post-processor.go; DO NOT EDIT MANUALLY -->
|
||||
|
||||
- `impersonated_service_account` (string) - This allows service account impersonation as per the docs.
|
||||
- `impersonate_service_account` (string) - This allows service account impersonation as per the [docs](https://cloud.google.com/iam/docs/impersonating-service-accounts).
|
||||
|
||||
- `gcs_object_name` (string) - The name of the GCS object in `bucket` where
|
||||
the RAW disk image will be copied for import. This is treated as a
|
||||
|
|
Loading…
Reference in New Issue