0

When I login to Google Console and open the cloud shell, I have a (Bash) shell, and using the "three dots" menu, I can upload a file to this instance: enter image description here

How can I do that using my local command line (i.e. from my own OS running on my laptop)? I guess I need the name of the running instance, how do I find that?

John Hanley
  • 74,467
  • 6
  • 95
  • 159
TMOTTM
  • 3,286
  • 6
  • 32
  • 63
  • Each time you start Cloud Shell it gets a different DNS name. If you watch my website this weekend, I am about to release a new article that documents how to interface with Cloud Shell from your desktop including the source code to a program that launches Putty connected to Cloud Shell, remote command execution plus file upload and download capabilities. This program means that you can script commands, file transfers, etc from your desktop to/from CloudShell. www.jhanley.com Full source code will be on GitHub. – John Hanley Jun 29 '19 at 19:23
  • Source code released. Written in Go. My article still needs to be completed: https://www.jhanley.com/google-cloud-shell-cli-in-go/ – John Hanley Jun 30 '19 at 00:34
  • Thanks @JohnHanley, looks like quite an effort you made there. So you're wrapping the SDK gcloud somehow to obtain the instance name of cloud shell VM? – TMOTTM Jun 30 '19 at 09:46
  • I am calling the Cloud Shell REST API to get information on the Cloud Shell instance for the currently authenticated user. Each Google Cloud user has his/her own Cloud Shell instance. Read the source code module https://github.com/jhanley-com/google-cloud-shell-cli-go/blob/master/cloudshell.go to learn more. – John Hanley Jun 30 '19 at 14:23

1 Answers1

0

To get the name of the current Cloud Shell instance you can call the Cloud Shell REST API. This endpoint will return JSON describing the instance:

https://cloud.google.com/shell/docs/reference/rest/v1alpha1/users.environments/get

The return JSON looks like this:

{
  "name": "users/john.smith@example.com/environments/default",
  "id": "default",
  "dockerImage": "gcr.io/cloudshell-images/cloudshell:latest",
  "state": "RUNNING",
  "sshUsername": "john_smith,
  "sshHost": "devshell-vm-5ee6f5d4-3c46-4fee-8865-dc0978b5af98.cloudshell.dev",
  "sshPort": 6000,
  "publicKeys": [
    {
      "name": "users/me/environments/default/publicKeys/8b4afb8d-5fd9-1234-85d9-9527393ea7ca",
      "format": "SSH_RSA",
      "key": "<removed>"
    },
    {
      "name": "users/me/environments/default/publicKeys/0a580367-fd88-56ae-dc4e-5295ee29784e",
      "format": "SSH_RSA",
      "key": "<removed>"
    }
  ]
}

I have published a full program written in Go that interfaces with Google Cloud Shell. This includes executing remote commands, uploading files, download files and launching Putty with an SSH connection.

Google Cloud Shell CLI in Go

The following example shows how to call the Cloud Shell REST API to get the instance information:

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "time"
    "github.com/kirinlabs/HttpRequest"
)

//******************************************************************************************
// Cloud Shell State
//
// https://cloud.google.com/shell/docs/reference/rest/Shared.Types/State
//
// STATE_UNSPECIFIED    The environment's states is unknown.
// DISABLED     The environment is not running and can't be connected to.
//          Starting the environment will transition it to the STARTING state.
// STARTING     The environment is being started but is not yet ready to accept
//          connections.
// RUNNING      The environment is running and ready to accept connections. It
//          will automatically transition back to DISABLED after a period of
//          inactivity or if another environment is started.
//******************************************************************************************

//******************************************************************************************
// https://cloud.google.com/shell/docs/reference/rest/Shared.Types/Environment
//******************************************************************************************

type CloudShellEnv struct {
    Name                 string   `json:"name"`
    Id                   string   `json:"id"`
    DockerImage          string   `json:"dockerImage"`
    State                string   `json:"state"`
    SshUsername          string   `json:"sshUsername"`
    SshHost              string   `json:"sshHost"`
    SshPort              int32   `json:"sshPort"`
    Error struct {
        Code              int32   `json:"code"`
        Message           string  `json:"message"`
        Status            string  `json:"status"`
    } `json:"error"`
}

//******************************************************************************************
// Method: users.environments.get
// https://cloud.google.com/shell/docs/reference/rest/v1alpha1/users.environments/get
//******************************************************************************************

func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShellEnv, error) {
    //************************************************************
    //
    //************************************************************

    var params CloudShellEnv

    endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default"
    endpoint += "?alt=json"

    req := HttpRequest.NewRequest()

    req.SetHeaders(map[string]string{
            "Authorization": "Bearer " + accessToken,
            "X-Goog-User-Project": config.ProjectId})

    //************************************************************
    //
    //************************************************************

    res, err := req.Get(endpoint)

    if err != nil {
        fmt.Println("Error: ", err)
        return params, err
    }

    body, err := res.Body()

    if err != nil {
        fmt.Println("Error: ", err)
        return params, err
    }

    if flag_info == true {
        fmt.Println("")
        fmt.Println("************************************************************")
        fmt.Println("Cloud Shell Info:")
        fmt.Println(string(body))
        fmt.Println("************************************************************")
    }

    err = json.Unmarshal(body, &params)

    if err != nil {
        fmt.Println("Error: Cannot unmarshal JSON: ", err)
        return params, err
    }

    if params.Error.Code != 0 {
        fmt.Println("")
        fmt.Println(params.Error.Message)
    }

    return params, nil
}
John Hanley
  • 74,467
  • 6
  • 95
  • 159