identity_vm.go (3398B)
1 // Copyright 2011 Google Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 // +build !appengine 6 7 package internal 8 9 import ( 10 "log" 11 "net/http" 12 "os" 13 "strings" 14 15 netcontext "golang.org/x/net/context" 16 ) 17 18 // These functions are implementations of the wrapper functions 19 // in ../appengine/identity.go. See that file for commentary. 20 21 const ( 22 hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname" 23 hRequestLogId = "X-AppEngine-Request-Log-Id" 24 hDatacenter = "X-AppEngine-Datacenter" 25 ) 26 27 func ctxHeaders(ctx netcontext.Context) http.Header { 28 c := fromContext(ctx) 29 if c == nil { 30 return nil 31 } 32 return c.Request().Header 33 } 34 35 func DefaultVersionHostname(ctx netcontext.Context) string { 36 return ctxHeaders(ctx).Get(hDefaultVersionHostname) 37 } 38 39 func RequestID(ctx netcontext.Context) string { 40 return ctxHeaders(ctx).Get(hRequestLogId) 41 } 42 43 func Datacenter(ctx netcontext.Context) string { 44 if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" { 45 return dc 46 } 47 // If the header isn't set, read zone from the metadata service. 48 // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE] 49 zone, err := getMetadata("instance/zone") 50 if err != nil { 51 log.Printf("Datacenter: %v", err) 52 return "" 53 } 54 parts := strings.Split(string(zone), "/") 55 if len(parts) == 0 { 56 return "" 57 } 58 return parts[len(parts)-1] 59 } 60 61 func ServerSoftware() string { 62 // TODO(dsymonds): Remove fallback when we've verified this. 63 if s := os.Getenv("SERVER_SOFTWARE"); s != "" { 64 return s 65 } 66 if s := os.Getenv("GAE_ENV"); s != "" { 67 return s 68 } 69 return "Google App Engine/1.x.x" 70 } 71 72 // TODO(dsymonds): Remove the metadata fetches. 73 74 func ModuleName(_ netcontext.Context) string { 75 if s := os.Getenv("GAE_MODULE_NAME"); s != "" { 76 return s 77 } 78 if s := os.Getenv("GAE_SERVICE"); s != "" { 79 return s 80 } 81 return string(mustGetMetadata("instance/attributes/gae_backend_name")) 82 } 83 84 func VersionID(_ netcontext.Context) string { 85 if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" { 86 return s1 + "." + s2 87 } 88 if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" { 89 return s1 + "." + s2 90 } 91 return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version")) 92 } 93 94 func InstanceID() string { 95 if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" { 96 return s 97 } 98 if s := os.Getenv("GAE_INSTANCE"); s != "" { 99 return s 100 } 101 return string(mustGetMetadata("instance/attributes/gae_backend_instance")) 102 } 103 104 func partitionlessAppID() string { 105 // gae_project has everything except the partition prefix. 106 if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" { 107 return appID 108 } 109 if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" { 110 return project 111 } 112 return string(mustGetMetadata("instance/attributes/gae_project")) 113 } 114 115 func fullyQualifiedAppID(_ netcontext.Context) string { 116 if s := os.Getenv("GAE_APPLICATION"); s != "" { 117 return s 118 } 119 appID := partitionlessAppID() 120 121 part := os.Getenv("GAE_PARTITION") 122 if part == "" { 123 part = string(mustGetMetadata("instance/attributes/gae_partition")) 124 } 125 126 if part != "" { 127 appID = part + "~" + appID 128 } 129 return appID 130 } 131 132 func IsDevAppServer() bool { 133 return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" 134 }