3946ea6ad8f57628f22b006e3acc365cc0d8136c — Louis Solofrizzo 3 months ago 8f54cb4 master
csc, api: Add csc instance show command

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>
6 files changed, 206 insertions(+), 15 deletions(-)

M api/database.go
M api/instance.go
M api/jobs.go
A csc/cmd/instance/show.go
M sdk/instance.go
M sdk/request.go
M api/database.go => api/database.go +2 -0
@@ 42,6 42,7 @@ Uuid         string
  	Name         string
  	Ipv4         uint
+ 	Ipv4Private  string
  	Size         uint
  	OS           string
  	Architecture string


@@ 49,6 50,7 @@ Type         string
  	Status       string
  	Ipv6         string
+ 	Ipv6Mask     string
  	LXCStatus    string
  }
  

M api/instance.go => api/instance.go +5 -14
@@ 49,26 49,14 @@ func instance_get(ctx iris.Context) {
  	var entry DbInstance
  	var result cisco.Instance
- 	var ipv6 string
  	var status string
  
  	user := ctx.Values().Get("User")
  	instance := ctx.Params().Get("name")
  	DB.First(&entry, "user = ? AND name = ?", user, instance)
  
- 	inst, _, _ := Context.LXD.GetInstanceState("LF" + entry.Uuid)
- 
- 	for _, net := range inst.Network {
- 		for _, addr := range net.Addresses {
- 			if addr.Family == "inet6" && !strings.HasPrefix(addr.Address, "fe80") && addr.Scope != "local" {
- 				ipv6 = addr.Address
- 				break
- 			}
- 		}
- 	}
- 
  	if entry.Status == "LXD" {
- 		status = inst.Status
+ 		status = entry.LXCStatus
  	} else {
  		status = entry.Status
  	}


@@ 80,7 68,9 @@ OS:           entry.OS,
  		Architecture: entry.Architecture,
  		Status:       status,
- 		Ipv6:         ipv6,
+ 		Ipv6:         entry.Ipv6,
+ 		Ipv6Mask:     entry.Ipv6Mask,
+ 		Ipv4Private:  entry.Ipv4Private,
  		Type:         entry.Type,
  	}
  


@@ 590,6 580,7 @@   func InitInstanceRoutes(app *iris.Application) {
  	app.Get("/instance", APIAuth, instance_list)
+ 	app.Get("/instance/{name:string}", APIAuth, instance_get)
  	app.Post("/instance", APIAuth, instance_new)
  	app.Put("/instance/start/{name:string}", APIAuth, instance_start)
  	app.Put("/instance/stop/{name:string}", APIAuth, instance_stop)

M api/jobs.go => api/jobs.go +8 -1
@@ 14,6 14,8 @@ DB.Find(&entries)
  		for _, instance := range entries {
  			var ipv6 string = ""
+ 			var ipv6_mask string = ""
+ 			var ipv4 string = ""
  
  			if instance.Status == "LXD" {
  				c1 := make(chan *api.InstanceState, 1)


@@ 33,13 35,18 @@ for _, addr := range net.Addresses {
  							if addr.Family == "inet6" && !strings.HasPrefix(addr.Address, "fe80") && addr.Scope != "local" {
  								ipv6 = addr.Address
- 								break
+ 								ipv6_mask = addr.Netmask
+ 							}
+ 							if addr.Family == "inet" && addr.Scope != "local" {
+ 								ipv4 = addr.Address
  							}
  						}
  					}
  
  					if ipv6 != "" {
  						DB.Model(&instance).Update("ipv6", ipv6)
+ 						DB.Model(&instance).Update("ipv6_mask", ipv6_mask)
+ 						DB.Model(&instance).Update("ipv4_private", ipv4)
  					}
  					DB.Model(&instance).Update("lxc_status", inst.Status)
  				case <-time.After(30 * time.Second):

A csc/cmd/instance/show.go => csc/cmd/instance/show.go +168 -0
@@ 0,0 1,168 @@
+ package instance
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ type Row struct {
+ 	title string
+ 	value string
+ }
+ 
+ var TableSize int = 120
+ 
+ func printSep(num int) {
+ 	var i int = 0
+ 	var sep int = 0
+ 
+ 	if num > 0 {
+ 		sep = TableSize / num
+ 	}
+ 
+ 	for i <= TableSize {
+ 		if i == 0 || i == TableSize || (num != 0 && i%sep == 0) {
+ 			fmt.Printf("+")
+ 		} else {
+ 			fmt.Printf("-")
+ 		}
+ 
+ 		i = i + 1
+ 	}
+ 
+ 	fmt.Printf("\n")
+ }
+ 
+ func printWithPad(row Row, max int) {
+ 	var length int = len(row.title) + len(row.value) + 2
+ 
+ 	fmt.Printf("\033[1;39m%s:\033[0m %s", row.title, row.value)
+ 	for length < max {
+ 		fmt.Printf(" ")
+ 		length = length + 1
+ 	}
+ }
+ 
+ func printRows(rows []Row) {
+ 	printSep(len(rows))
+ 
+ 	fmt.Printf("|")
+ 
+ 	for _, row := range rows {
+ 		fmt.Printf(" ")
+ 		printWithPad(row, (TableSize/len(rows))-2)
+ 		fmt.Printf("|")
+ 	}
+ 	fmt.Printf("\n")
+ }
+ 
+ var instanceShow = &cobra.Command{
+ 	Use:   "show",
+ 	Short: "Show an instance",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		instance, err := cisco.ShowInstance(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 		printRows([]Row{{
+ 			title: "Name",
+ 			value: instance.Name,
+ 		}})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "Status",
+ 				value: instance.Status,
+ 			},
+ 			{
+ 				title: "Type",
+ 				value: instance.Type,
+ 			},
+ 			{
+ 				title: "Image",
+ 				value: instance.OS,
+ 			},
+ 			{
+ 				title: "Region",
+ 				value: "fr-par",
+ 			},
+ 		})
+ 		printRows([]Row{
+ 			{
+ 				title: "Instance ID",
+ 				value: instance.Uuid,
+ 			},
+ 			{
+ 				title: "Image ID",
+ 				value: "",
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "Volumes",
+ 				value: "1",
+ 			},
+ 			{
+ 				title: "Storage",
+ 				value: strconv.Itoa(int(instance.Size)) + "GB",
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "Public IP",
+ 				value: "None",
+ 			},
+ 			{
+ 				title: "Private IP",
+ 				value: instance.Ipv4Private,
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "IPv6",
+ 				value: instance.Ipv6,
+ 			},
+ 			{
+ 				title: "Netmask",
+ 				value: instance.Ipv6Mask,
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "SSH Command",
+ 				value: "ssh root@" + instance.Ipv6,
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "Public DNS",
+ 				value: instance.Uuid + ".public.louifox.house",
+ 			},
+ 		})
+ 
+ 		printRows([]Row{
+ 			{
+ 				title: "Private DNS",
+ 				value: instance.Uuid + ".internal.louifox.house",
+ 			},
+ 		})
+ 
+ 		printSep(0)
+ 
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.InstanceRootCmd.AddCommand(instanceShow)
+ }

M sdk/instance.go => sdk/instance.go +17 -0
@@ 10,7 10,9 @@ Name         string    `json:"name"`
  	Status       string    `json:"status"`
  	Ipv4         string    `json:"ipv4"`
+ 	Ipv4Private  string    `json:"ipv4_private"`
  	Ipv6         string    `json:"ipv6"`
+ 	Ipv6Mask     string    `json:"ipv6_mask"`
  	Size         uint      `json:"size"`
  	OS           string    `json:"os"`
  	Architecture string    `json:"architecture"`


@@ 40,6 42,21 @@ return result, err
  }
  
+ func ShowInstance(name string) (Instance, error) {
+ 	var result Instance
+ 
+ 	data, err := SendRequest(InstanceShowRoute, Request{
+ 		Arg: name,
+ 	})
+ 
+ 	if err != nil {
+ 		return result, err
+ 	}
+ 
+ 	err = json.Unmarshal(data.([]byte), &result)
+ 	return result, err
+ }
+ 
  type InstanceNew struct {
  	Name string `json:"name"`
  	OS   string `json:"os"`

M sdk/request.go => sdk/request.go +6 -0
@@ 146,6 146,12 @@ Protected: true,
  }
  
+ var InstanceShowRoute Route = Route{
+ 	Path:      "/instance",
+ 	Method:    "GET",
+ 	Protected: true,
+ }
+ 
  var InstanceNewRoute Route = Route{
  	Path:      "/instance",
  	Method:    "POST",