Last active
December 9, 2017 05:48
-
-
Save maripiyoko/5ac9237cfb70d4d584361a7ced8f3d2d to your computer and use it in GitHub Desktop.
gcp instance up, down, check status by GAE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
runtime: go | |
api_version: go1 | |
handlers: | |
- url: /.* | |
script: _go_app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package minecraft | |
import ( | |
"fmt" | |
"net/http" | |
"encoding/json" | |
"golang.org/x/net/context" | |
"golang.org/x/oauth2" | |
"golang.org/x/oauth2/google" | |
appengine "google.golang.org/appengine" | |
compute "google.golang.org/api/compute/v1" | |
"google.golang.org/appengine/urlfetch" | |
) | |
func init() { | |
http.HandleFunc("/minecraft", handler) | |
} | |
type SlackResponse struct { | |
Response_type string `json:"response_type"` | |
Text string `json:"text"` | |
} | |
func handler(w http.ResponseWriter, r *http.Request) { | |
project := "YOUR_GCP_PROJECT_NAME" | |
zone := "YOUR_GCP_ZONE" | |
instance := "YOUR_GCP_INSTANCE_NAME" | |
// check token | |
token := r.PostFormValue("token") | |
if token != "YOUR_SLACK_TOKEN" { | |
w.WriteHeader(http.StatusUnauthorized) | |
writeSlackMessage(w, "NG") | |
return | |
} | |
// check option either status | up | down | |
option := r.PostFormValue("text") | |
if option == "status" { | |
sendExternalIp(w, r, project, zone, instance) | |
} else if option == "up" { | |
startInstance(w, r, project, zone, instance) | |
} else if option == "down" { | |
stopInstance(w, r, project, zone, instance) | |
} else { | |
w.WriteHeader(http.StatusNotAcceptable) | |
writeSlackMessage(w, "invalid option") | |
} | |
} | |
func sendExternalIp(w http.ResponseWriter, r *http.Request, project string, zone string, instance string) { | |
ctx := appengine.NewContext(r) | |
s, err := NewComputeService(ctx, w) | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
is := compute.NewInstancesService(s) | |
insList, err := is.List(project, zone).Do() | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
for _, ins := range insList.Items { | |
name := ins.Name | |
status := ins.Status | |
if name == instance { | |
if status == "RUNNING" { | |
natIp := ins.NetworkInterfaces[0].AccessConfigs[0].NatIP | |
if natIp != "" { | |
message := fmt.Sprintf("Minecraft server is running on : %s:25565", natIp) | |
writeSlackMessage(w, message) | |
} | |
} else { | |
message := fmt.Sprintf("instance status is %s", status) | |
writeSlackMessage(w, message) | |
} | |
} | |
} | |
} | |
func startInstance(w http.ResponseWriter, r *http.Request, project string, zone string, instance string) { | |
ctx := appengine.NewContext(r) | |
s, err := NewComputeService(ctx, w) | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
is := compute.NewInstancesService(s) | |
insList, err := is.List(project, zone).Do() | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
for _, ins := range insList.Items { | |
name := ins.Name | |
status := ins.Status | |
if name == instance { | |
if status == "RUNNING" { | |
writeSlackMessage(w, "instance is already RUNNING") | |
} else { | |
_, err := is.Start(project, zone, instance).Do() | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
writeSlackMessage(w, "Instance is starting now... wait for seconds..") | |
} | |
} | |
} | |
} | |
func stopInstance(w http.ResponseWriter, r *http.Request, project string, zone string, instance string) { | |
ctx := appengine.NewContext(r) | |
s, err := NewComputeService(ctx, w) | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
is := compute.NewInstancesService(s) | |
insList, err := is.List(project, zone).Do() | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
for _, ins := range insList.Items { | |
name := ins.Name | |
status := ins.Status | |
if name == instance { | |
if status != "RUNNING" { | |
message := fmt.Sprintf("instance status is %s", status) | |
writeSlackMessage(w, message) | |
} else { | |
_, err := is.Stop(project, zone, instance).Do() | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
writeSlackMessage(w, "Instance is stopping now...") | |
} | |
} | |
} | |
} | |
func writeSlackMessage(w http.ResponseWriter, message string) { | |
slack_response := SlackResponse{"in_channel", message} | |
//io.WriteString(w, body) | |
json, err := json.Marshal(slack_response) | |
if err != nil { | |
fmt.Fprint(w, err) | |
return | |
} | |
w.Header().Set("Content-Type", "application/json") | |
w.Write(json) | |
} | |
func NewComputeService(ctx context.Context, w http.ResponseWriter) (*compute.Service, error) { | |
client := &http.Client{ | |
Transport: &oauth2.Transport{ | |
Source: google.AppEngineTokenSource(ctx, compute.ComputeScope), | |
Base: &urlfetch.Transport{Context: ctx}, | |
}, | |
} | |
s, err := compute.New(client) | |
if err != nil { | |
fmt.Fprint(w, err) | |
return nil, err | |
} | |
return s, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment