a8004773671b4e4dbb006e7d2af9a47b49a1048e — Louis Solofrizzo 10 months ago 5b54cda
csc, sdk, api: Add instance types

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>
M api/admin.go => api/admin.go +179 -1
@@ 233,8 233,177 @@ ctx.JSON(result)
  }
  
+ func admin_instance_create(ctx iris.Context) {
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID != 0 {
+ 		APIError(ctx, 409, "An instance type with this name already exists, please update it or delete it.")
+ 		return
+ 	}
+ 
+ 	instanceType.Name = name
+ 	instanceType.CPU = 1
+ 	instanceType.Memory = 256
+ 	instanceType.Architecture = "x86_64"
+ 	instanceType.Type = "container"
+ 	instanceType.Enabled = false
+ 
+ 	DB.Create(&instanceType)
+ 	ctx.StatusCode(iris.StatusCreated)
+ }
+ 
+ func admin_instance_list(ctx iris.Context) {
+ 	var result []cisco.InstanceType
+ 	var instanceTypes []DbInstanceType
+ 
+ 	DB.Find(&instanceTypes)
+ 	for _, instanceType := range instanceTypes {
+ 		result = append(result, cisco.InstanceType{
+ 			Name:         instanceType.Name,
+ 			CPU:          instanceType.CPU,
+ 			Memory:       instanceType.Memory,
+ 			Architecture: instanceType.Architecture,
+ 			Type:         instanceType.Type,
+ 			Enabled:      instanceType.Enabled,
+ 		})
+ 	}
+ 
+ 	ctx.JSON(&result)
+ }
+ 
+ func admin_instance_get(ctx iris.Context) {
+ 	var result cisco.InstanceType
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	DB.First(&instanceType, "name = ?", name)
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	result = cisco.InstanceType{
+ 		Name:         instanceType.Name,
+ 		CPU:          instanceType.CPU,
+ 		Memory:       instanceType.Memory,
+ 		Architecture: instanceType.Architecture,
+ 		Type:         instanceType.Type,
+ 		Enabled:      instanceType.Enabled,
+ 	}
+ 	ctx.JSON(&result)
+ }
+ 
+ func admin_instance_delete(ctx iris.Context) {
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	instanceType.Name = name
+ 	DB.Delete(&instanceType)
+ }
+ 
+ func admin_instance_arch(ctx iris.Context) {
+ 	var arch cisco.InstanceTypeArchUpdate
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	ctx.ReadJSON(&arch)
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	if ArchitectureIsValid(ctx, arch.Arch) != nil {
+ 		return
+ 	}
+ 
+ 	DB.Model(&instanceType).Update("architecture", arch.Arch)
+ }
+ 
+ func admin_instance_cpu(ctx iris.Context) {
+ 	var cpu cisco.InstanceTypeCPUUpdate
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	ctx.ReadJSON(&cpu)
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	DB.Model(&instanceType).Update("cpu", cpu.CPU)
+ }
+ 
+ func admin_instance_memory(ctx iris.Context) {
+ 	var memory cisco.InstanceTypeMemoryUpdate
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	ctx.ReadJSON(&memory)
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	DB.Model(&instanceType).Update("memory", memory.Memory)
+ }
+ 
+ func admin_instance_type(ctx iris.Context) {
+ 	var Itype cisco.InstanceTypeTypeUpdate
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	ctx.ReadJSON(&Itype)
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	if Itype.Type != "container" && Itype.Type != "virtual-machine" {
+ 		APIError(ctx, 400, "Wrong instance type. Must be one of 'container' or 'virtual'.")
+ 		return
+ 	}
+ 
+ 	DB.Model(&instanceType).Update("type", Itype.Type)
+ }
+ 
+ func admin_instance_enable(ctx iris.Context) {
+ 	var enable cisco.InstanceTypeEnableUpdate
+ 	var instanceType DbInstanceType
+ 
+ 	name := ctx.Params().Get("name")
+ 	ctx.ReadJSON(&enable)
+ 	DB.First(&instanceType, "name = ?", name)
+ 
+ 	if instanceType.ID == 0 {
+ 		APIError(ctx, 404, "Cannot find the desired instance type")
+ 		return
+ 	}
+ 
+ 	DB.Model(&instanceType).Update("enabled", enable.Enable)
+ }
+ 
  func InitAdminRoutes(app *iris.Application) {
  	app.Get("/admin/user/list", AdminAuth, admin_user_list)
+ 	app.Get("/admin/user/{username:string}", AdminAuth, admin_user_info)
+ 
  	app.Get("/admin/quota/list", AdminAuth, admin_quota_list)
  	app.Get("/admin/quota/{name:string}", AdminAuth, admin_quota_get)
  	app.Put("/admin/quota/{name:string}", AdminAuth, admin_quota_create)


@@ 243,5 412,14 @@ app.Post("/admin/quota/ipv4/{name:string}", AdminAuth, admin_quota_ipv4)
  	app.Post("/admin/quota/storage/{name:string}", AdminAuth, admin_quota_storage)
  	app.Post("/admin/quota/invites/{name:string}", AdminAuth, admin_quota_invites)
- 	app.Get("/admin/user/{username:string}", AdminAuth, admin_user_info)
+ 
+ 	app.Put("/admin/instance/{name:string}", AdminAuth, admin_instance_create)
+ 	app.Get("/admin/instance/list", AdminAuth, admin_instance_list)
+ 	app.Get("/admin/instance/{name:string}", AdminAuth, admin_instance_get)
+ 	app.Delete("/admin/instance/{name:string}", AdminAuth, admin_instance_delete)
+ 	app.Post("/admin/instance/arch/{name:string}", AdminAuth, admin_instance_arch)
+ 	app.Post("/admin/instance/cpu/{name:string}", AdminAuth, admin_instance_cpu)
+ 	app.Post("/admin/instance/memory/{name:string}", AdminAuth, admin_instance_memory)
+ 	app.Post("/admin/instance/type/{name:string}", AdminAuth, admin_instance_type)
+ 	app.Post("/admin/instance/enable/{name:string}", AdminAuth, admin_instance_enable)
  }

M api/database.go => api/database.go +11 -0
@@ 66,6 66,16 @@ User    uint
  }
  
+ type DbInstanceType struct {
+ 	gorm.Model
+ 	Name         string
+ 	Architecture string
+ 	CPU          int
+ 	Memory       int
+ 	Enabled      bool
+ 	Type         string
+ }
+ 
  var DB *gorm.DB
  
  func InitDB() {


@@ 83,6 93,7 @@ DB.AutoMigrate(&DbInstance{})
  	DB.AutoMigrate(&DbIpv4{})
  	DB.AutoMigrate(&DbInvite{})
+ 	DB.AutoMigrate(&DbInstanceType{})
  }
  
  func CloseDB() {

M api/instance.go => api/instance.go +57 -5
@@ 7,6 7,7 @@ "github.com/kataras/iris"
  	"github.com/lxc/lxd/shared/api"
  	"github.com/satori/go.uuid"
+ 	"strconv"
  	"strings"
  )
  


@@ 43,6 44,7 @@ Ipv4:         ipv4.IP,
  			Status:       inst.Status,
  			Ipv6:         ipv6,
+ 			Type:         instance.Type,
  		})
  	}
  


@@ 52,6 54,7 @@ func ArchitectureIsValid(ctx iris.Context, name string) error {
  	var Architectures []string = []string{
  		"x86_64",
+ 		"arm",
  	}
  
  	for _, v := range Architectures {


@@ 64,9 67,38 @@ return errors.New("The specified Architecture is not valid")
  }
  
+ func TypeIsValid(ctx iris.Context, name string) error {
+ 	var instanceTypes []DbInstanceType
+ 
+ 	DB.Find(&instanceTypes, "enabled = ?", true)
+ 
+ 	for _, instanceType := range instanceTypes {
+ 		if instanceType.Name == name {
+ 			return nil
+ 		}
+ 	}
+ 
+ 	APIError(ctx, 400, "The specified Instance Type is not valid")
+ 	return errors.New("The specified Instance Type is not valid")
+ }
+ 
  func createBackendInstance(instance DbInstance) error {
+ 	var instanceType DbInstanceType
+ 
+ 	DB.First(&instanceType, "name = ?", instance.Type)
+ 	if instanceType.ID == 0 {
+ 		return errors.New("The specified Instance Type is not valid")
+ 	}
+ 
  	op, err := Context.LXD.CreateContainer(api.ContainersPost{
  		Name: "LF" + instance.Uuid,
+ 		ContainerPut: api.ContainerPut{
+ 			Architecture: instanceType.Architecture,
+ 			Config: map[string]string{
+ 				"limits.cpu":    strconv.Itoa(instanceType.CPU),
+ 				"limits.memory": strconv.Itoa(instanceType.Memory) + "MB",
+ 			},
+ 		},
  		Source: api.ContainerSource{
  			Type:  "image",
  			Alias: instance.OS,


@@ 102,8 134,8 @@ return
  	}
  
- 	if instance.Architecture == "" {
- 		APIErrorField(ctx, "architecture")
+ 	if instance.Type == "" {
+ 		APIErrorField(ctx, "type")
  		return
  	}
  


@@ 111,7 143,7 @@ return
  	}
  
- 	if ArchitectureIsValid(ctx, instance.Architecture) != nil {
+ 	if TypeIsValid(ctx, instance.Type) != nil {
  		return
  	}
  


@@ 137,10 169,9 @@   	entry.Uuid = uuid.NewV4().String()
  	entry.Name = instance.Name
- 	entry.Architecture = instance.Architecture
+ 	entry.Type = instance.Type
  	entry.OS = instance.OS
  	entry.Size = 10
- 	entry.Type = "LXC"
  	entry.User, _ = ctx.Values().GetUint("User")
  
  	if createBackendInstance(entry) != nil {


@@ 315,6 346,26 @@ }
  }
  
+ func instance_types(ctx iris.Context) {
+ 	var result []cisco.InstanceType
+ 	var instanceTypes []DbInstanceType
+ 
+ 	DB.Find(&instanceTypes, "enabled = ?", true)
+ 
+ 	for _, instanceType := range instanceTypes {
+ 		result = append(result, cisco.InstanceType{
+ 			Name:         instanceType.Name,
+ 			CPU:          instanceType.CPU,
+ 			Memory:       instanceType.Memory,
+ 			Architecture: instanceType.Architecture,
+ 			Type:         instanceType.Type,
+ 			Enabled:      instanceType.Enabled,
+ 		})
+ 	}
+ 
+ 	ctx.JSON(&result)
+ }
+ 
  func InitInstanceRoutes(app *iris.Application) {
  	app.Get("/instance", APIAuth, instance_list)
  	app.Post("/instance", APIAuth, instance_new)


@@ 323,4 374,5 @@ app.Delete("/instance/{name:string}", APIAuth, instance_delete)
  	app.Get("/instance/keys/{name:string}", instance_keys)
  	app.Get("/instance/name/{name:string}", instance_name)
+ 	app.Get("/instance/types", APIAuth, instance_types)
  }

M api/invite.go => api/invite.go +2 -2
@@ 16,11 16,11 @@   You can either activate it via the webinterface[1], or via the command line tool[2]:
  
-     csc invite claim %s --endpoint https://api.%s
+     csc invite claim %s --endpoint %s
  
  Take Care,
  
- [1] https://%s/invite/claim/%s
+ [1] %s/invite/claim/%s
  [2] https://louifox.s3.fr-par.scw.cloud/cisco/csc/latest/csc
  `
  

A csc/cmd/admin/instance.go => csc/cmd/admin/instance.go +15 -0
@@ 0,0 1,15 @@
+ package admin
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceRootCmd = &cobra.Command{
+ 	Use:   "instance",
+ 	Short: "Administrator utilities for instance",
+ }
+ 
+ func init() {
+ 	cmd.AdminRootCmd.AddCommand(AdminInstanceRootCmd)
+ }

A csc/cmd/admin/instance/create.go => csc/cmd/admin/instance/create.go +25 -0
@@ 0,0 1,25 @@
+ package admininstance
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceCreateRootCmd = &cobra.Command{
+ 	Use:   "create",
+ 	Short: "Create a new instance type",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.CreateInstanceType(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminInstanceRootCmd.AddCommand(AdminInstanceCreateRootCmd)
+ }

A csc/cmd/admin/instance/delete.go => csc/cmd/admin/instance/delete.go +25 -0
@@ 0,0 1,25 @@
+ package admininstance
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceDeleteRootCmd = &cobra.Command{
+ 	Use:   "delete",
+ 	Short: "Delete an instance type",
+ 	Args:  cobra.ExactArgs(1),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		err := cisco.DeleteInstanceType(args[0])
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminInstanceRootCmd.AddCommand(AdminInstanceDeleteRootCmd)
+ }

A csc/cmd/admin/instance/list.go => csc/cmd/admin/instance/list.go +36 -0
@@ 0,0 1,36 @@
+ package admininstance
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/olekukonko/tablewriter"
+ 	"github.com/spf13/cobra"
+ 	"os"
+ 	"strconv"
+ )
+ 
+ var AdminInstanceListRootCmd = &cobra.Command{
+ 	Use:   "list",
+ 	Short: "List instances type",
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		instance, err := cisco.ListInstanceType()
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		table := tablewriter.NewWriter(os.Stdout)
+ 		table.SetHeader([]string{"Name", "Architecture", "CPU", "Memory", "Type", "Enabled"})
+ 
+ 		for _, inst := range instance {
+ 			table.Append([]string{inst.Name, inst.Architecture, strconv.Itoa(inst.CPU), strconv.Itoa(inst.Memory) + "MB", inst.Type, strconv.FormatBool(inst.Enabled)})
+ 		}
+ 		table.Render()
+ 	},
+ }
+ 
+ func init() {
+ 	admin.AdminInstanceRootCmd.AddCommand(AdminInstanceListRootCmd)
+ }

A csc/cmd/admin/instance/update.go => csc/cmd/admin/instance/update.go +15 -0
@@ 0,0 1,15 @@
+ package admininstance
+ 
+ import (
+ 	"cisco/csc/cmd/admin"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceUpdateRootCmd = &cobra.Command{
+ 	Use:   "update",
+ 	Short: "Update instance values",
+ }
+ 
+ func init() {
+ 	admin.AdminInstanceRootCmd.AddCommand(AdminInstanceUpdateRootCmd)
+ }

A csc/cmd/admin/instance/update/architecture.go => csc/cmd/admin/instance/update/architecture.go +26 -0
@@ 0,0 1,26 @@
+ package admininstanceupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/instance"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceUpdateArchitectureRootCmd = &cobra.Command{
+ 	Use:   "architecture",
+ 	Short: "Update instances architecture",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 
+ 		err := cisco.UpdateInstanceTypeArch(args[0], args[1])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admininstance.AdminInstanceUpdateRootCmd.AddCommand(AdminInstanceUpdateArchitectureRootCmd)
+ }

A csc/cmd/admin/instance/update/cpu.go => csc/cmd/admin/instance/update/cpu.go +36 -0
@@ 0,0 1,36 @@
+ package admininstanceupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/instance"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminInstanceUpdateCPURootCmd = &cobra.Command{
+ 	Use:   "cpu",
+ 	Short: "Update instances cpu number",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 
+ 		var cpu int
+ 		var err error
+ 
+ 		cpu, err = strconv.Atoi(args[1])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		err = cisco.UpdateInstanceTypeCPU(args[0], cpu)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admininstance.AdminInstanceUpdateRootCmd.AddCommand(AdminInstanceUpdateCPURootCmd)
+ }

A csc/cmd/admin/instance/update/enable.go => csc/cmd/admin/instance/update/enable.go +36 -0
@@ 0,0 1,36 @@
+ package admininstanceupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/instance"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceUpdateEnableRootCmd = &cobra.Command{
+ 	Use:   "enable",
+ 	Short: "Update instances enable",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		var enable bool
+ 
+ 		if args[1] == "true" {
+ 			enable = true
+ 		} else if args[1] == "false" {
+ 			enable = false
+ 		} else {
+ 			fmt.Printf("Error: '%s' is not a boolean\n", args[1])
+ 			return
+ 		}
+ 
+ 		err := cisco.UpdateInstanceTypeEnable(args[0], enable)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admininstance.AdminInstanceUpdateRootCmd.AddCommand(AdminInstanceUpdateEnableRootCmd)
+ }

A csc/cmd/admin/instance/update/memory.go => csc/cmd/admin/instance/update/memory.go +36 -0
@@ 0,0 1,36 @@
+ package admininstanceupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/instance"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ 	"strconv"
+ )
+ 
+ var AdminInstanceUpdateMemoryRootCmd = &cobra.Command{
+ 	Use:   "memory",
+ 	Short: "Update instances memory number",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 
+ 		var memory int
+ 		var err error
+ 
+ 		memory, err = strconv.Atoi(args[1])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		err = cisco.UpdateInstanceTypeMemory(args[0], memory)
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admininstance.AdminInstanceUpdateRootCmd.AddCommand(AdminInstanceUpdateMemoryRootCmd)
+ }

A csc/cmd/admin/instance/update/type.go => csc/cmd/admin/instance/update/type.go +26 -0
@@ 0,0 1,26 @@
+ package admininstanceupdate
+ 
+ import (
+ 	"cisco/csc/cmd/admin/instance"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/spf13/cobra"
+ )
+ 
+ var AdminInstanceUpdateTypeRootCmd = &cobra.Command{
+ 	Use:   "type",
+ 	Short: "Update instances type",
+ 	Args:  cobra.ExactArgs(2),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 
+ 		err := cisco.UpdateInstanceTypeType(args[0], args[1])
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 	},
+ }
+ 
+ func init() {
+ 	admininstance.AdminInstanceUpdateRootCmd.AddCommand(AdminInstanceUpdateTypeRootCmd)
+ }

M csc/cmd/instance/list.go => csc/cmd/instance/list.go +2 -2
@@ 23,9 23,9 @@ }
  
  		table := tablewriter.NewWriter(os.Stdout)
- 		table.SetHeader([]string{"Name", "Status", "OS", "Ipv6", "Size"})
+ 		table.SetHeader([]string{"Name", "Status", "Type", "OS", "Ipv6", "Size"})
  		for _, instance := range instances {
- 			table.Append([]string{instance.Name, instance.Status, instance.OS, instance.Ipv6, strconv.FormatInt(int64(instance.Size), 10) + "GB"})
+ 			table.Append([]string{instance.Name, instance.Status, instance.Type, instance.OS, instance.Ipv6, strconv.FormatInt(int64(instance.Size), 10) + "GB"})
  		}
  		table.Render()
  	},

M csc/cmd/instance/new.go => csc/cmd/instance/new.go +5 -4
@@ 10,15 10,16 @@ var instanceNew = &cobra.Command{
  	Use:   "new",
  	Short: "Create a new instance",
- 	Args:  cobra.ExactArgs(2),
+ 	Args:  cobra.ExactArgs(3),
  	Run: func(cmd *cobra.Command, args []string) {
  		name := args[0]
  		os := args[1]
+ 		model := args[2]
  
  		err := cisco.NewInstance(cisco.InstanceNew{
- 			Name:         name,
- 			OS:           os,
- 			Architecture: "x86_64",
+ 			Name: name,
+ 			OS:   os,
+ 			Type: model,
  		})
  
  		if err != nil {

A csc/cmd/instance/types.go => csc/cmd/instance/types.go +38 -0
@@ 0,0 1,38 @@
+ package instance
+ 
+ import (
+ 	"cisco/csc/cmd"
+ 	"cisco/sdk"
+ 	"fmt"
+ 	"github.com/olekukonko/tablewriter"
+ 	"github.com/spf13/cobra"
+ 	"os"
+ 	"strconv"
+ )
+ 
+ var instanceTypes = &cobra.Command{
+ 	Use:   "types",
+ 	Short: "List Instances types",
+ 	Args:  cobra.ExactArgs(0),
+ 	Run: func(cmd *cobra.Command, args []string) {
+ 		instance, err := cisco.ListInstanceTypes()
+ 
+ 		if err != nil {
+ 			fmt.Printf("Error: %s\n", err.Error())
+ 			return
+ 		}
+ 
+ 		table := tablewriter.NewWriter(os.Stdout)
+ 		table.SetHeader([]string{"Name", "Architecture", "CPU", "Memory", "Type"})
+ 
+ 		for _, inst := range instance {
+ 			table.Append([]string{inst.Name, inst.Architecture, strconv.Itoa(inst.CPU), strconv.Itoa(inst.Memory) + "MB", inst.Type})
+ 		}
+ 		table.Render()
+ 
+ 	},
+ }
+ 
+ func init() {
+ 	cmd.InstanceRootCmd.AddCommand(instanceTypes)
+ }

M csc/main.go => csc/main.go +2 -0
@@ 3,6 3,8 @@ import (
  	"cisco/csc/cmd"
  	_ "cisco/csc/cmd/admin"
+ 	_ "cisco/csc/cmd/admin/instance"
+ 	_ "cisco/csc/cmd/admin/instance/update"
  	_ "cisco/csc/cmd/admin/quotas"
  	_ "cisco/csc/cmd/admin/quotas/update"
  	_ "cisco/csc/cmd/admin/user"

M sdk/instance.go => sdk/instance.go +144 -3
@@ 18,6 18,15 @@ Created      time.Time `json:"created"`
  }
  
+ type InstanceType struct {
+ 	Name         string `json:"name"`
+ 	Architecture string `json:"architecture"`
+ 	CPU          int    `json:"cpu"`
+ 	Memory       int    `json:"memory"`
+ 	Type         string `json:"type"`
+ 	Enabled      bool   `json:"enabled"`
+ }
+ 
  func ListInstance() ([]Instance, error) {
  	var result []Instance
  


@@ 32,9 41,9 @@ }
  
  type InstanceNew struct {
- 	Name         string `json:"name"`
- 	OS           string `json:"os"`
- 	Architecture string `json:"architecture"`
+ 	Name string `json:"name"`
+ 	OS   string `json:"os"`
+ 	Type string `json:"type"`
  }
  
  func NewInstance(instance InstanceNew) error {


@@ 68,3 77,135 @@   	return err
  }
+ 
+ func CreateInstanceType(name string) error {
+ 	_, err := SendRequest(AdminInstanceTypeCreateRoute, Request{
+ 		Arg: name,
+ 	})
+ 
+ 	return err
+ }
+ 
+ func DeleteInstanceType(name string) error {
+ 	_, err := SendRequest(AdminInstanceTypeDeleteRoute, Request{
+ 		Arg: name,
+ 	})
+ 
+ 	return err
+ }
+ 
+ func ListInstanceType() ([]InstanceType, error) {
+ 	var result []InstanceType
+ 
+ 	data, err := SendRequest(AdminInstanceTypeListRoute, Request{})
+ 
+ 	if err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	err = json.Unmarshal(data.([]byte), &result)
+ 	return result, err
+ }
+ 
+ func GetInstanceType(name string) (InstanceType, error) {
+ 	var result InstanceType
+ 
+ 	data, err := SendRequest(AdminInstanceTypeGetRoute, Request{
+ 		Arg: name,
+ 	})
+ 
+ 	if err != nil {
+ 		return result, err
+ 	}
+ 
+ 	err = json.Unmarshal(data.([]byte), &result)
+ 	return result, err
+ }
+ 
+ type InstanceTypeArchUpdate struct {
+ 	Arch string `json:"arch"`
+ }
+ 
+ func UpdateInstanceTypeArch(name string, architecture string) error {
+ 	_, err := SendRequest(AdminInstanceTypeUpdateArchRoute, Request{
+ 		Arg: name,
+ 		Data: &InstanceTypeArchUpdate{
+ 			Arch: architecture,
+ 		},
+ 	})
+ 
+ 	return err
+ }
+ 
+ type InstanceTypeCPUUpdate struct {
+ 	CPU int `json:"cpu"`
+ }
+ 
+ func UpdateInstanceTypeCPU(name string, cpu int) error {
+ 	_, err := SendRequest(AdminInstanceTypeUpdateCPURoute, Request{
+ 		Arg: name,
+ 		Data: &InstanceTypeCPUUpdate{
+ 			CPU: cpu,
+ 		},
+ 	})
+ 
+ 	return err
+ }
+ 
+ type InstanceTypeMemoryUpdate struct {
+ 	Memory int `json:"cpu"`
+ }
+ 
+ func UpdateInstanceTypeMemory(name string, memory int) error {
+ 	_, err := SendRequest(AdminInstanceTypeUpdateMemoryRoute, Request{
+ 		Arg: name,
+ 		Data: &InstanceTypeMemoryUpdate{
+ 			Memory: memory,
+ 		},
+ 	})
+ 
+ 	return err
+ }
+ 
+ type InstanceTypeTypeUpdate struct {
+ 	Type string `json:"string"`
+ }
+ 
+ func UpdateInstanceTypeType(name string, instanceType string) error {
+ 	_, err := SendRequest(AdminInstanceTypeUpdateTypeRoute, Request{
+ 		Arg: name,
+ 		Data: &InstanceTypeTypeUpdate{
+ 			Type: instanceType,
+ 		},
+ 	})
+ 
+ 	return err
+ }
+ 
+ type InstanceTypeEnableUpdate struct {
+ 	Enable bool `json:"enable"`
+ }
+ 
+ func UpdateInstanceTypeEnable(name string, enable bool) error {
+ 	_, err := SendRequest(AdminInstanceTypeUpdateEnableRoute, Request{
+ 		Arg: name,
+ 		Data: &InstanceTypeEnableUpdate{
+ 			Enable: enable,
+ 		},
+ 	})
+ 
+ 	return err
+ }
+ 
+ func ListInstanceTypes() ([]InstanceType, error) {
+ 	var result []InstanceType
+ 
+ 	data, err := SendRequest(InstanceTypesRoute, Request{})
+ 
+ 	if err != nil {
+ 		return nil, err
+ 	}
+ 
+ 	err = json.Unmarshal(data.([]byte), &result)
+ 	return result, err
+ }

M sdk/request.go => sdk/request.go +60 -0
@@ 164,12 164,72 @@ Protected: true,
  }
  
+ var InstanceTypesRoute Route = Route{
+ 	Path:      "/instance/types",
+ 	Method:    "GET",
+ 	Protected: true,
+ }
+ 
  var ImageListRoute Route = Route{
  	Path:      "/image",
  	Method:    "GET",
  	Protected: true,
  }
  
+ var AdminInstanceTypeCreateRoute Route = Route{
+ 	Path:      "/admin/instance",
+ 	Method:    "PUT",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeDeleteRoute Route = Route{
+ 	Path:      "/admin/instance",
+ 	Method:    "DELETE",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeListRoute Route = Route{
+ 	Path:      "/admin/instance/list",
+ 	Method:    "GET",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeGetRoute Route = Route{
+ 	Path:      "/admin/instance",
+ 	Method:    "GET",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeUpdateArchRoute Route = Route{
+ 	Path:      "/admin/instance/arch",
+ 	Method:    "POST",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeUpdateCPURoute Route = Route{
+ 	Path:      "/admin/instance/cpu",
+ 	Method:    "POST",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeUpdateMemoryRoute Route = Route{
+ 	Path:      "/admin/instance/memory",
+ 	Method:    "POST",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeUpdateTypeRoute Route = Route{
+ 	Path:      "/admin/instance/type",
+ 	Method:    "POST",
+ 	Protected: true,
+ }
+ 
+ var AdminInstanceTypeUpdateEnableRoute Route = Route{
+ 	Path:      "/admin/instance/enable",
+ 	Method:    "POST",
+ 	Protected: true,
+ }
+ 
  type Request struct {
  	Arg  string
  	Data interface{}