func getRemoteContext(host string) (context.Context, error) { var hc *http.Client var err error const defaultCredentialEnvKey = "GOOGLE_APPLICATION_CREDENTIALS" if os.Getenv(defaultCredentialEnvKey) != "" { hc, err = google.DefaultClient(oauth2.NoContext, remoteCtxScopes...) } else { return nil, errNoRemoteAPIKeyIsConfigured } if err != nil { return nil, err } return remote_api.NewRemoteContext(host, hc) }
// UseRemote is the same as Use, except that it lets you attach a context to // a remote host using the Remote API feature. See the docs for the // prerequisites. // // docs: https://cloud.google.com/appengine/docs/go/tools/remoteapi // // inOutCtx will be replaced with the new, derived context, if err is nil, // otherwise it's unchanged and continues to be safe-to-use. // // If client is nil, this will use create a new client, and will try to be // clever about it: // * If you're creating a remote context FROM AppEngine, this will use // urlfetch.Transport. This can be used to allow app-to-app remote_api // control. // // * If host starts with "localhost", this will create a regular http.Client // with a cookiejar, and call the _ah/login API to log in as an admin with // the user "*****@*****.**". // // * Otherwise, it will create a Google OAuth2 client with the following scopes: // - "https://www.googleapis.com/auth/appengine.apis" // - "https://www.googleapis.com/auth/userinfo.email" // - "https://www.googleapis.com/auth/cloud.platform" func UseRemote(inOutCtx *context.Context, host string, client *http.Client) (err error) { if client == nil { if strings.HasPrefix(host, "localhost") { transp := http.DefaultTransport if aeCtx := AEContextNoTxn(*inOutCtx); aeCtx != nil { transp = urlfetch.Get(*inOutCtx) } client = &http.Client{Transport: transp} client.Jar, err = cookiejar.New(nil) if err != nil { return } u := fmt.Sprintf("http://%s/_ah/login?%s", host, url.Values{ "email": {"*****@*****.**"}, "admin": {"True"}, "action": {"Login"}, }.Encode()) var rsp *http.Response rsp, err = client.Get(u) if err != nil { return } defer rsp.Body.Close() } else { aeCtx := AEContextNoTxn(*inOutCtx) if aeCtx == nil { aeCtx = context.Background() } client, err = gOAuth.DefaultClient(aeCtx, "https://www.googleapis.com/auth/appengine.apis", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/cloud.platform", ) if err != nil { return } } } aeCtx, err := remote_api.NewRemoteContext(host, client) if err != nil { return } *inOutCtx = setupAECtx(*inOutCtx, aeCtx) return nil }
func main() { flag.Parse() client, err := newClient() if err != nil { log.Fatal(err) } c, err := remote_api.NewRemoteContext(host, client) if err != nil { log.Fatalf("Error loading RemoteContext: %s", err.Error()) } switch { case dump != "": log.Printf("Dumping entities of kind %s...\n", dump) err = aetools.Dump(c, os.Stdout, &aetools.Options{Kind: dump, PrettyPrint: pretty}) if err != nil { log.Fatal(err) } case len(load) > 0: log.Println("Loading entities ...") for _, f := range load { fd, err := os.Open(f) if err != nil { log.Printf("Error opening %s\n", err.Error()) continue } err = aetools.Load(c, fd, &aetools.Options{ BatchSize: batchSize, }) if err != nil { log.Printf("Error loading fixture %s: %s\n", f, err.Error()) } fd.Close() } default: err = aetools.Dump(c, os.Stdout, &aetools.Options{Kind: StatKind, PrettyPrint: true}) if err != nil { log.Fatal(err) } } }
func newRemoteAPIContext(req *wcg.Request, host string) (context.Context, error) { // TODO: migrate file to datastore? if !lib.IsOnLocalGAE() && !req.IsTest() { return nil, fmt.Errorf("RemoteAPI use on GAE is not supported yet.") } var hc *http.Client var err error const defaultCredentialEnvKey = "GOOGLE_APPLICATION_CREDENTIALS" if os.Getenv(defaultCredentialEnvKey) != "" { hc, err = google.DefaultClient(gae.NewContext(req), remoteCtxScopes...) } else { return nil, ErrNoRemoteAPIKeyIsConfigured } if err != nil { return nil, err } return remote_api.NewRemoteContext(host, hc) }
func main() { const host = "<your-app-id>.appspot.com" ctx := context.Background() hc, err := google.DefaultClient(ctx, "https://www.googleapis.com/auth/appengine.apis", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/cloud-platform", ) if err != nil { log.Fatal(err) } remoteCtx, err := remote_api.NewRemoteContext(host, hc) if err != nil { log.Fatal(err) } q := datastore.NewQuery("Greeting"). Filter("Date >=", time.Now().AddDate(0, 0, -7)) log.Println(q.Count(remoteCtx)) }
///////////////////////////////////////////////// // This allows us to use the remote_api ///////////////////////////////////////////////// func (session *Session) Context() (c context.Context, err error) { return remote_api.NewRemoteContext(session.AppHost, session.client) }