Skip to content

Instantly share code, notes, and snippets.

@veggiemonk
Created May 17, 2019 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veggiemonk/54a7593bbbf05c31e47d128a50cb3897 to your computer and use it in GitHub Desktop.
Save veggiemonk/54a7593bbbf05c31e47d128a50cb3897 to your computer and use it in GitHub Desktop.
forseti-viz server in csv
package main
import (
"database/sql"
"fmt"
"net/http"
"os"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/cors"
"github.com/go-chi/render"
_ "github.com/go-sql-driver/mysql"
)
type Node struct {
ID int `json:"id"`
ResourceType string `json:"resource_type"`
Category string `json:"category"`
ResourceID string `json:"resource_id"`
ParentID int `json:"parent_id"`
ResourceDisplayName string `json:"resource_data_displayname"`
ResourceName string `json:"resource_data_name"`
}
var query = `
SELECT id,
resource_type,
category,
resource_id,
IFNULL(parent_id, 0) as parent_id,
IFNULL(resource_data ->> '$.displayName', '') as resource_data_displayname,
IFNULL(resource_data ->> '$.name', '') as resource_data_name
FROM gcp_inventory
WHERE inventory_index_id = (SELECT id FROM inventory_index ORDER BY completed_at_datetime DESC LIMIT 1)
AND (category = 'resource')
AND (resource_type = 'organization' OR resource_type = 'project' OR resource_type = 'folder' OR
resource_type = 'appengine_app' OR resource_type = 'kubernetes_cluster' OR resource_type = 'cloudsqlinstance' OR
resource_type = 'instance' OR resource_type = 'instance_group' OR resource_type = 'instancetemplate' OR
resource_type = 'disk' OR resource_type = 'bucket'
)`
func main() {
dbUser := os.Getenv("DB_USER")
dbPass := os.Getenv("DB_PASS")
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbName := os.Getenv("DB_NAME")
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8", dbUser, dbPass, dbHost, dbPort, dbName))
if err != nil {
panic(err.Error())
}
defer db.Close()
// Open doesn't open a connection. Validate DSN data:
err = db.Ping()
if err != nil {
panic(err.Error()) // proper error handling instead of panic in your app
}
// Execute the query
rows, err := db.Query(query)
if err != nil {
panic(err.Error())
}
defer rows.Close()
payload := make([]byte, 0)
for rows.Next() {
data := new(Node)
err := rows.Scan(
&data.ID,
&data.ResourceType,
&data.Category,
&data.ResourceID,
&data.ParentID,
&data.ResourceDisplayName,
&data.ResourceName,
)
if err != nil {
panic(err.Error())
}
payload = append(payload, []byte(fmt.Sprintf("%d,%s,%s,%s,%d,%s,%s\n",
data.ID,
data.ResourceType,
data.Category,
data.ResourceID,
data.ParentID,
data.ResourceDisplayName,
data.ResourceName,
))...)
}
r := chi.NewRouter()
cors := cors.New(cors.Options{
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
AllowedOrigins: []string{"*"},
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
AllowedMethods: []string{"GET"}, //, "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
// ExposedHeaders: []string{"Link"},
AllowCredentials: true,
MaxAge: 300, // Maximum value not ignored by any of major browsers
})
r.Use(cors.Handler)
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.URLFormat)
r.Use(render.SetContentType(render.ContentTypePlainText))
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write(payload)
})
fmt.Println("Starting...")
http.ListenAndServe(":3000", r)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment