From a9fa39a0371271d7710e40ad0a78319e808174a9 Mon Sep 17 00:00:00 2001 From: Deepali Date: Thu, 5 Apr 2018 03:14:19 +0000 Subject: [PATCH] Added code for gcp cloud --- virtualmachine/gcp/util.go | 59 ++++++++++++-------------------------- virtualmachine/gcp/vm.go | 43 +++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/virtualmachine/gcp/util.go b/virtualmachine/gcp/util.go index e6f7b781..335718c0 100644 --- a/virtualmachine/gcp/util.go +++ b/virtualmachine/gcp/util.go @@ -6,10 +6,8 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "net" "net/http" - "os" "strings" "time" "context" @@ -43,11 +41,18 @@ type googleResManService struct { service *googleresourcemanager.Service } -// accountFile represents the structure of the account file JSON file. -type accountFile struct { - PrivateKey string `json:"private_key"` - ClientEmail string `json:"client_email"` - ClientId string `json:"client_id"` +// AccountFile represents the structure of the account file JSON file. +type AccountFile struct { + AuthProviderX509CertURL string `json:"auth_provider_x509_cert_url"` + AuthURI string `json:"auth_uri"` + ClientEmail string `json:"client_email"` + ClientId string `json:"client_id"` + ClientX509CertURL string `json:"client_x509_cert_url"` + PrivateKey string `json:"private_key"` + PrivateKeyId string `json:"private_key_id"` + ProjectId string `json:"project_id"` + TokenURI string `json:"token_uri"` + Type string `json:"type"` } // getResManService processes the account file and returns the service object @@ -56,15 +61,11 @@ func (acc *Account) getResManService() (*googleResManService, error) { var err error var client *http.Client - if err = parseAccountFile(&acc.account, acc.AccountFile); err != nil { - return nil, err - } - // Auth with AccountFile first if provided - if acc.account.PrivateKey != "" { + if acc.Account.PrivateKey != "" { config := jwt.Config{ - Email: acc.account.ClientEmail, - PrivateKey: []byte(acc.account.PrivateKey), + Email: acc.Account.ClientEmail, + PrivateKey: []byte(acc.Account.PrivateKey), Scopes: acc.Scopes, TokenURL: tokenURL, } @@ -90,15 +91,11 @@ func (vm *VM) getService() (*googleService, error) { var err error var client *http.Client - if err = parseAccountFile(&vm.account, vm.AccountFile); err != nil { - return nil, err - } - // Auth with AccountFile first if provided - if vm.account.PrivateKey != "" { + if vm.Account.PrivateKey != "" { config := jwt.Config{ - Email: vm.account.ClientEmail, - PrivateKey: []byte(vm.account.PrivateKey), + Email: vm.Account.ClientEmail, + PrivateKey: []byte(vm.Account.PrivateKey), Scopes: vm.Scopes, TokenURL: tokenURL, } @@ -445,26 +442,6 @@ func parseAccountJSON(result interface{}, jsonText string) error { return dec.Decode(result) } -func parseAccountFile(file *accountFile, account string) error { - if err := parseAccountJSON(file, account); err != nil { - if _, err = os.Stat(account); os.IsNotExist(err) { - return fmt.Errorf("error finding account file: %s", account) - } - - bytes, err := ioutil.ReadFile(account) - if err != nil { - return fmt.Errorf("error reading account file from path '%s': %s", file, err) - } - - err = parseAccountJSON(file, string(bytes)) - if err != nil { - return fmt.Errorf("error parsing account file: %s", err) - } - } - - return nil -} - func (svc *googleService) getSSHKey() string { return fmt.Sprintf("%s:%s\n", svc.vm.SSHCreds.SSHUser, svc.vm.SSHPublicKey) } diff --git a/virtualmachine/gcp/vm.go b/virtualmachine/gcp/vm.go index c962d9d4..52c85767 100644 --- a/virtualmachine/gcp/vm.go +++ b/virtualmachine/gcp/vm.go @@ -3,6 +3,7 @@ package gcp import ( + "encoding/json" "errors" "fmt" "net" @@ -45,6 +46,7 @@ var ( type VM struct { Name string Description string + Region string Zone string MachineType string Preemptible bool // Preemptible instances will be terminates after they run for 24 hours. @@ -64,7 +66,7 @@ type VM struct { Tags []string //Instance Tags AccountFile string - account accountFile + Account AccountFile SSHCreds ssh.Credentials SSHPublicKey string @@ -206,7 +208,7 @@ type Account struct { AccountFile string // account: Represents a structure containing private key, client email // and client ID parsed from AccountFile - account accountFile + Account AccountFile // Scopes: Represents access scopes with which API call is made Scopes []string } @@ -225,11 +227,47 @@ type Project struct { CreateTime string `json:"create_time,omitempty"` } +// Packer visor image config for GCP cloud +type GcpConfig struct { + AccountFile string `json:"account_file"` + ProjectID string `json:"project_id"` + SourceImage string `json:"source_image"` + SSHUsername string `json:"ssh_username,omitempty"` + Type string `json:"type"` + Zone string `json:"zone"` + StartupScript string `json:"startup_script_file"` + ImageName string `json:"image_name,omitempty"` +} + +// Packer visor image config for GCP cloud +type VisorImageConfig struct { + Builders []GcpConfig `json:"builders"` +} + // GetName returns the name of the virtual machine. func (vm *VM) GetName() string { return vm.Name } +// Creates a visor image config required for packer +func (vm *VM) CreateVisorImageConfig(accountFile, packerConf string) ([]byte, error) { + var vig VisorImageConfig + var conf GcpConfig + + conf.ImageName = vm.Name + conf.AccountFile = accountFile + conf.Zone = vm.Zone + conf.SourceImage = vm.SourceImage + conf.ProjectID = vm.Project + conf.Type = "googlecompute" + conf.StartupScript = packerConf + conf.SSHUsername = "apporbit" + + vig.Builders = append(vig.Builders, conf) + + return json.Marshal(vig) +} + // Provision creates a virtual machine on GCE. It returns an error if // there was a problem during creation. func (vm *VM) Provision() error { @@ -524,6 +562,7 @@ func (vm *VM) GetZoneList() ([]Zone, error) { Region: regionName, Status: zone.Status, }) + } return response, nil