// newGCECloud creates a new instance of GCECloud. func newGCECloud() (*GCECloud, error) { projectID, zone, err := getProjectAndZone() if err != nil { return nil, err } // TODO: if we want to use this on a machine that doesn't have the http://metadata server // e.g. on a user's machine (not VM) somewhere, we need to have an alternative for // instance id lookup. instanceID, err := getInstanceID() if err != nil { return nil, err } client, err := serviceaccount.NewClient(&serviceaccount.Options{}) if err != nil { return nil, err } svc, err := compute.New(client) if err != nil { return nil, err } return &GCECloud{ service: svc, projectID: projectID, zone: zone, instanceID: instanceID, }, nil }
// newGCECloud creates a new instance of GCECloud. func newGCECloud() (*GCECloud, error) { projectID, zone, err := getProjectAndZone() if err != nil { return nil, err } // TODO: if we want to use this on a machine that doesn't have the http://metadata server // e.g. on a user's machine (not VM) somewhere, we need to have an alternative for // instance id lookup. instanceID, err := getInstanceID() if err != nil { return nil, err } client := oauth2.NewClient(oauth2.NoContext, google.ComputeTokenSource("")) svc, err := compute.New(client) if err != nil { return nil, err } containerSvc, err := container.New(client) if err != nil { return nil, err } return &GCECloud{ service: svc, containerService: containerSvc, projectID: projectID, zone: zone, instanceID: instanceID, }, nil }
func computeMain(client *http.Client, argv []string) { if len(argv) != 2 { fmt.Fprintln(os.Stderr, "Usage: compute project_id instance_name (to start an instance)") return } service, _ := compute.New(client) projectId := argv[0] instanceName := argv[1] prefix := "https://www.googleapis.com/compute/v1/projects/" + projectId imageURL := "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140606" zone := "us-central1-a" // Show the current images that are available. res, err := service.Images.List(projectId).Do() log.Printf("Got compute.Images.List, err: %#v, %v", res, err) instance := &compute.Instance{ Name: instanceName, Description: "compute sample instance", MachineType: prefix + "/zones/" + zone + "/machineTypes/n1-standard-1", Disks: []*compute.AttachedDisk{ { AutoDelete: true, Boot: true, Type: "PERSISTENT", InitializeParams: &compute.AttachedDiskInitializeParams{ DiskName: "my-root-pd", SourceImage: imageURL, }, }, }, NetworkInterfaces: []*compute.NetworkInterface{ &compute.NetworkInterface{ AccessConfigs: []*compute.AccessConfig{ &compute.AccessConfig{ Type: "ONE_TO_ONE_NAT", Name: "External NAT", }, }, Network: prefix + "/global/networks/default", }, }, ServiceAccounts: []*compute.ServiceAccount{ { Email: "default", Scopes: []string{ compute.DevstorageFull_controlScope, compute.ComputeScope, }, }, }, } op, err := service.Instances.Insert(projectId, zone, instance).Do() log.Printf("Got compute.Operation, err: %#v, %v", op, err) }
// newGCECloud creates a new instance of GCECloud. func newGCECloud(config io.Reader) (*GCECloud, error) { projectID, zone, err := getProjectAndZone() if err != nil { return nil, err } // TODO: if we want to use this on a machine that doesn't have the http://metadata server // e.g. on a user's machine (not VM) somewhere, we need to have an alternative for // instance id lookup. instanceID, err := getInstanceID() if err != nil { return nil, err } externalID, err := getCurrentExternalID() if err != nil { return nil, err } networkName, err := getNetworkName() if err != nil { return nil, err } tokenSource := google.ComputeTokenSource("") if config != nil { var cfg Config if err := gcfg.ReadInto(&cfg, config); err != nil { glog.Errorf("Couldn't read config: %v", err) return nil, err } if cfg.Global.ProjectID != "" { projectID = cfg.Global.ProjectID } if cfg.Global.NetworkName != "" { networkName = cfg.Global.NetworkName } if cfg.Global.TokenURL != "" { tokenSource = newAltTokenSource(cfg.Global.TokenURL) } } client := oauth2.NewClient(oauth2.NoContext, tokenSource) svc, err := compute.New(client) if err != nil { return nil, err } containerSvc, err := container.New(client) if err != nil { return nil, err } return &GCECloud{ service: svc, containerService: containerSvc, projectID: projectID, zone: zone, instanceID: instanceID, externalID: externalID, networkName: networkName, metadataAccess: getMetadata, }, nil }
// Create a GCE Cloud instance. func NewGCECloud() Cloud { // Set up a gcloud transport. transport, err := gcloudTransport() if err != nil { log.Fatalf("unable to create gcloud transport: %v", err) } svc, err := compute.New(transport.Client()) if err != nil { log.Fatalf("Error creating service: %v", err) } return &GCECloud{ service: svc, projectId: *projectId, } }
func NewGCECloud() (*GCECloud, error) { projectID, zone, err := getProjectAndZone() if err != nil { return nil, err } client, err := serviceaccount.NewClient(&serviceaccount.Options{}) if err != nil { return nil, err } svc, err := compute.New(client) if err != nil { return nil, err } return &GCECloud{ service: svc, projectID: projectID, zone: zone, }, nil }
// Create a GCE Cloud instance. 'clientId', 'clientSecret' and 'scope' are used to ask for a client // credential. 'code' is optional and is only used if a cached credential can not be found. // 'projectId' is the Google Cloud project name. func NewCloudGCE(projectId string) (cloud *GCECloud, err error) { conf := &gceConfig{} if err = conf.Read(); err != nil || conf.Credential.RefreshToken == "" { return nil, errors.New("Did you authorize the client? Run `docker-cloud auth`.") } if projectId == "" { if conf.ProjectId == "" { return nil, errors.New("Did you define project id? Run `docker-cloud start -project=<project-id>`") } projectId = conf.ProjectId } oAuth2Conf := newGCEOAuth2Config(conf.Credential.ClientId, conf.Credential.ClientSecret, conf.Key.Scope) transport := &oauth.Transport{ Config: oAuth2Conf, // Make the actual request using the cached token to authenticate. // ("Here's the token, let me in!") Token: &oauth.Token{RefreshToken: conf.Credential.RefreshToken}, Transport: http.DefaultTransport, } // TODO(jbd): Does it need to refresh the token, transport will auto do it if // it fails with an auth error on the first request. err = transport.Refresh() if err != nil { return } svc, err := compute.New(transport.Client()) if err != nil { return } return &GCECloud{ service: svc, projectId: projectId, }, nil }
func main() { flag.Parse() if *proj == "" { log.Fatalf("Missing --project flag") } prefix := "https://www.googleapis.com/compute/v1/projects/" + *proj machType := prefix + "/zones/" + *zone + "/machineTypes/" + *mach tr := &oauth.Transport{ Config: config, } tokenCache := oauth.CacheFile("token.dat") token, err := tokenCache.Token() if err != nil { if *writeObject != "" { log.Fatalf("Can't use --write_object without a valid token.dat file already cached.") } log.Printf("Error getting token from %s: %v", string(tokenCache), err) log.Printf("Get auth code from %v", config.AuthCodeURL("my-state")) fmt.Print("\nEnter auth code: ") sc := bufio.NewScanner(os.Stdin) sc.Scan() authCode := strings.TrimSpace(sc.Text()) token, err = tr.Exchange(authCode) if err != nil { log.Fatalf("Error exchanging auth code for a token: %v", err) } tokenCache.PutToken(token) } tr.Token = token oauthClient := &http.Client{Transport: tr} if *writeObject != "" { writeCloudStorageObject(oauthClient) return } computeService, _ := compute.New(oauthClient) natIP := *staticIP if natIP == "" { // Try to find it by name. aggAddrList, err := computeService.Addresses.AggregatedList(*proj).Do() if err != nil { log.Fatal(err) } // http://godoc.org/code.google.com/p/google-api-go-client/compute/v1#AddressAggregatedList IPLoop: for _, asl := range aggAddrList.Items { for _, addr := range asl.Addresses { if addr.Name == *instName+"-ip" && addr.Status == "RESERVED" { natIP = addr.Address break IPLoop } } } } cloudConfig := baseConfig if *sshPub != "" { key := strings.TrimSpace(readFile(*sshPub)) cloudConfig += fmt.Sprintf("\nssh_authorized_keys:\n - %s\n", key) } if os.Getenv("USER") == "bradfitz" { cloudConfig += fmt.Sprintf("\nssh_authorized_keys:\n - %s\n", "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwks9dwWKlRC+73gRbvYtVg0vdCwDSuIlyt4z6xa/YU/jTDynM4R4W10hm2tPjy8iR1k8XhDv4/qdxe6m07NjG/By1tkmGpm1mGwho4Pr5kbAAy/Qg+NLCSdAYnnE00FQEcFOC15GFVMOW2AzDGKisReohwH9eIzHPzdYQNPRWXE= [email protected]") } const maxCloudConfig = 32 << 10 // per compute API docs if len(cloudConfig) > maxCloudConfig { log.Fatalf("cloud config length of %d bytes is over %d byte limit", len(cloudConfig), maxCloudConfig) } instance := &compute.Instance{ Name: *instName, Description: "Go Builder", MachineType: machType, Disks: []*compute.AttachedDisk{instanceDisk(computeService)}, Tags: &compute.Tags{ Items: []string{"http-server", "https-server"}, }, Metadata: &compute.Metadata{ Items: []*compute.MetadataItems{ { Key: "user-data", Value: cloudConfig, }, }, }, NetworkInterfaces: []*compute.NetworkInterface{ &compute.NetworkInterface{ AccessConfigs: []*compute.AccessConfig{ &compute.AccessConfig{ Type: "ONE_TO_ONE_NAT", Name: "External NAT", NatIP: natIP, }, }, Network: prefix + "/global/networks/default", }, }, ServiceAccounts: []*compute.ServiceAccount{ { Email: "default", Scopes: []string{ compute.DevstorageFull_controlScope, compute.ComputeScope, }, }, }, } log.Printf("Creating instance...") op, err := computeService.Instances.Insert(*proj, *zone, instance).Do() if err != nil { log.Fatalf("Failed to create instance: %v", err) } opName := op.Name log.Printf("Created. Waiting on operation %v", opName) OpLoop: for { time.Sleep(2 * time.Second) op, err := computeService.ZoneOperations.Get(*proj, *zone, opName).Do() if err != nil { log.Fatalf("Failed to get op %s: %v", opName, err) } switch op.Status { case "PENDING", "RUNNING": log.Printf("Waiting on operation %v", opName) continue case "DONE": if op.Error != nil { for _, operr := range op.Error.Errors { log.Printf("Error: %+v", operr) } log.Fatalf("Failed to start.") } log.Printf("Success. %+v", op) break OpLoop default: log.Fatalf("Unknown status %q: %+v", op.Status, op) } } inst, err := computeService.Instances.Get(*proj, *zone, *instName).Do() if err != nil { log.Fatalf("Error getting instance after creation: %v", err) } ij, _ := json.MarshalIndent(inst, "", " ") log.Printf("Instance: %s", ij) }
// Create a GCE Cloud instance. 'clientId', 'clientSecret' and 'scope' are used to ask for a client // credential. 'code' is optional and is only used if a cached credential can not be found. // 'projectId' is the Google Cloud project name. func NewCloudGce(clientId string, clientSecret string, scope string, code string, projectId string) *GCECloud { // Set up a configuration. config := &oauth.Config{ ClientId: clientId, ClientSecret: clientSecret, RedirectURL: "oob", Scope: scope, AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", // TODO(bburns) : This prob. won't work on Windows TokenCache: oauth.CacheFile(os.Getenv("HOME") + "/cache.json"), AccessType: "offline", } // Set up a Transport using the config. // transport := &oauth.Transport{Config: config, // Transport: &LogTransport{http.DefaultTransport},} transport := &oauth.Transport{Config: config, Transport: http.DefaultTransport} // Try to pull the token from the cache; if this fails, we need to get one. token, err := config.TokenCache.Token() if err != nil { if clientId == "" || clientSecret == "" { flag.Usage() fmt.Fprint(os.Stderr, "Client id and secret are required.") os.Exit(2) } if code == "" { // Get an authorization code from the data provider. // ("Please ask the user if I can access this resource.") url := config.AuthCodeURL("") fmt.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE\n") fmt.Println(url) // The below doesn't work for some reason. Not sure why. I get 404's // fmt.Print("Enter code: ") // bio := bufio.NewReader(os.Stdin) // code, err = bio.ReadString('\n') // if err != nil { // log.Fatal("input: ", err) // } return nil } // Exchange the authorization code for an access token. // ("Here's the code you gave the user, now give me a token!") // TODO(bburns) : Put up a separate web end point to do the oauth dance, so a user can just go to a web page. token, err = transport.Exchange(code) if err != nil { log.Fatal("Exchange:", err) } // (The Exchange method will automatically cache the token.) log.Printf("Token is cached in %v", config.TokenCache) } // Make the actual request using the cached token to authenticate. // ("Here's the token, let me in!") transport.Token = token log.Print("refreshing token: %v", token) err = transport.Refresh() if err != nil { log.Fatalf("failed to refresh oauth token: %v", err) } log.Print("oauth token refreshed") svc, err := compute.New(transport.Client()) if err != nil { log.Printf("Error creating service: %v", err) } return &GCECloud{ service: svc, projectId: projectId, } }
func GetClient(project string, region string, cache_path string) (*Client, error) { cache, err := config.LoadCredCache(cache_path) if err != nil { return nil, err } if region == "" { region = defaultRegion } if cache.GCE.Project == "" { var project string fmt.Printf("google project id: ") _, err = fmt.Scanf("%s", &project) if err != nil { return nil, err } cache.GCE.Project = strings.TrimSpace(project) cache.Save() } if cache.GCE.SSOClientID == "" || cache.GCE.SSOClientSecret == "" { var client_id string var client_secret string fmt.Printf("google client id: ") _, err = fmt.Scanf("%s", &client_id) if err != nil { return nil, err } cache.GCE.SSOClientID = strings.TrimSpace(client_id) fmt.Printf("google client secret: ") _, err = fmt.Scanf("%s", &client_secret) if err != nil { return nil, err } cache.GCE.SSOClientSecret = strings.TrimSpace(client_secret) if err != nil { return nil, err } cache.Save() } cfg := &oauth.Config{ ClientId: cache.GCE.SSOClientID, ClientSecret: cache.GCE.SSOClientSecret, Scope: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/userinfo.email", RedirectURL: "http://localhost:8016/oauth2callback", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", } if cache.GCE.Token.Expiry.Before(time.Now()) { token, err := authRefreshToken(cfg) if err != nil { return nil, err } cache.GCE.Token = *token cache.Save() } token := &cache.GCE.Token transport := &oauth.Transport{ Config: cfg, Token: token, Transport: http.DefaultTransport, } svc, err := compute.New(transport.Client()) if err != nil { return nil, err } return &Client{ service: svc, cache: cache, region: region, project_id: cache.GCE.Project, }, nil }