Example #1
0
// addRawDisk adds storage in form of a raw disk to a server
// @client:   authenticated CLCv2 client
// @servname: server name
// @diskGB:   amount of storage in GB to add to @servname
func addRawDisk(client *clcv2.CLIClient, servname string, diskGB uint32) (statusId string) {
	/* First get the list of disks */
	server, err := client.GetServer(servname)
	if err != nil {
		exit.Fatalf("failed to list details of server %q: %s", servname, err)
	}

	disks := make([]clcv2.ServerAdditionalDisk, len(server.Details.Disks))
	for i := range server.Details.Disks {
		disks[i] = clcv2.ServerAdditionalDisk{
			Id:     server.Details.Disks[i].Id,
			SizeGB: server.Details.Disks[i].SizeGB,
		}
	}

	statusId, err = client.ServerSetDisks(servname, append(disks,
		clcv2.ServerAdditionalDisk{
			SizeGB: diskGB,
			Type:   "raw",
		}))
	if err != nil {
		exit.Fatalf("failed to update the disk configuration on %q: %s", servname, err)
	}
	return statusId
}
Example #2
0
// Print group hierarchy starting at @g, using initial indentation @indent.
func printGroupIPs(client *clcv2.CLIClient, root *clcv2.Group) {
	var serverPrinter = func(g *clcv2.Group, arg interface{}) interface{} {
		var indent = arg.(string)

		if g.Type == "default" {
			fmt.Printf("%s%s/\n", indent, g.Name)
		} else {
			fmt.Printf("%s[%s]/\n", indent, g.Name)
		}

		for _, l := range g.Links {
			if l.Rel == "server" {
				ips, err := client.GetServerIPs(l.Id)
				if err != nil {
					exit.Fatalf("failed to get IPs of %q in %s: %s", l.Id, g.Name, err)
				}

				servLine := fmt.Sprintf("%s%s", indent+"    ", l.Id)
				fmt.Printf("%-50s %s\n", servLine, strings.Join(ips, ", "))
			}
		}
		return indent + "    "
	}
	clcv2.VisitGroupHierarchy(root, serverPrinter, "")
}
Example #3
0
// Print server IP(s)
// @client:    authenticated CLCv2 Client
// @servname:  server name
func printServerIP(client *clcv2.CLIClient, servname string) {
	ips, err := client.GetServerIPs(servname)
	if err != nil {
		exit.Fatalf("failed get server %q IPs: %s", servname, err)
	}

	fmt.Printf("%-20s %s\n", servname+":", strings.Join(ips, ", "))
}
Example #4
0
// showTemplates prints the templates available in @region
func showTemplates(client *clcv2.CLIClient, region string) {
	capa, err := client.GetDeploymentCapabilities(region)
	if err != nil {
		exit.Fatalf("failed to query deployment capabilities of %s: %s", region, err)
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetAutoWrapText(false)

	/* Note: not displaying ReservedDrivePaths and DrivePathLength here, I don't understand their use. */
	/* Note: not listing Capabilities here, since the table gets too large for a single screen */
	table.SetHeader([]string{"Template Name", "Description", "OS", "Storage"})

	for _, tpl := range capa.Templates {
		table.Append([]string{tpl.Name, tpl.Description, tpl.OsType, fmt.Sprintf("%d GB", tpl.StorageSizeGB)})
	}
	table.Render()
}
Example #5
0
// showNetworks shows available networks in data centre location @location.
func showNetworks(client *clcv2.CLIClient, location string) {
	networks, err := client.GetNetworks(location)
	if err != nil {
		exit.Fatalf("failed to list networks in %s: %s", location, err)
	}

	if len(networks) == 0 {
		println("Empty result.")
	} else {
		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_RIGHT)
		table.SetAutoWrapText(false)

		table.SetHeader([]string{"CIDR", "Gateway", "VLAN", "Name", "Description", "Type", "ID"})
		for _, l := range networks {
			table.Append([]string{l.Cidr, l.Gateway, fmt.Sprint(l.Vlan), l.Name, l.Description, l.Type, l.Id})
		}
		table.Render()
	}
}
Example #6
0
// Show condensed details of multiple servers
// @client:    authenticated CLCv2 Client
// @servnames: server names
func showServers(client *clcv2.CLIClient, servnames ...string) {
	var truncate = func(s string, maxlen int) string {
		if len(s) >= maxlen {
			s = s[:maxlen]
		}
		return s
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetAutoWrapText(true)

	table.SetHeader([]string{
		"Name", "Group", "Description", "OS",
		"IP", "CPU", "Mem", "Storage",
		"Status", "Last Change",
	})

	for _, servname := range servnames {
		server, err := client.GetServer(servname)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to list details of server %q: %s", servname, err)
			continue
		}

		grp, err := client.GetGroup(server.GroupId)
		if err != nil {
			exit.Fatalf("failed to resolve %s group UUID: %s", servname, err)
		}

		IPs := []string{}
		for _, ip := range server.Details.IpAddresses {
			if ip.Public != "" {
				IPs = append(IPs, ip.Public)
			}
			if ip.Internal != "" {
				IPs = append(IPs, ip.Internal)
			}
		}

		status := server.Details.PowerState
		if server.Details.InMaintenanceMode {
			status = "MAINTENANCE"
		} else if server.Status != "active" {
			status = server.Status
		}

		desc := server.Description
		if server.IsTemplate {
			desc = "TPL: " + desc
		}

		modifiedStr := humanize.Time(server.ChangeInfo.ModifiedDate)
		/* The ModifiedBy field can be an email address, or an API Key (hex string) */
		if _, err := hex.DecodeString(server.ChangeInfo.ModifiedBy); err == nil {
			modifiedStr += " via API Key"
		} else {
			modifiedStr += " by " + truncate(server.ChangeInfo.ModifiedBy, 6)
		}

		// Append a tilde (~) to indicate it has snapshots
		serverName := server.Name
		if len(server.Details.Snapshots) > 0 {
			serverName += "~"
		}

		table.Append([]string{
			serverName, grp.Name, truncate(desc, 30), truncate(server.OsType, 15),
			strings.Join(IPs, " "),
			fmt.Sprint(server.Details.Cpu), fmt.Sprintf("%d G", server.Details.MemoryMb/1024),
			fmt.Sprintf("%d G", server.Details.StorageGb),
			status, modifiedStr,
		})
	}
	table.Render()
}
Example #7
0
// Show details of a single server
// @client:    authenticated CLCv2 Client
// @servname:  server name
func showServer(client *clcv2.CLIClient, servname string) {
	server, err := client.GetServer(servname)
	if err != nil {
		exit.Fatalf("failed to list details of server %q: %s", servname, err)
	}

	grp, err := client.GetGroup(server.GroupId)
	if err != nil {
		exit.Fatalf("failed to resolve group UUID: %s", err)
	}

	/* First public, then private */
	IPs := []string{}
	for _, ip := range server.Details.IpAddresses {
		if ip.Public != "" {
			IPs = append(IPs, ip.Public)
		}
	}
	for _, ip := range server.Details.IpAddresses {
		if ip.Internal != "" {
			IPs = append(IPs, ip.Internal)
		}
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.SetAutoFormatHeaders(false)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetAutoWrapText(true)

	// CPU, Memory, IP and Power status are not filled in until the server reaches 'active' state.
	if server.Status == "active" {
		table.SetHeader([]string{
			"Name", "Group", "Description", "OS",
			"CPU", "Mem", "IP", "Power",
			"Last Change",
		})

	} else {
		table.SetHeader([]string{
			"Name", "Group", "Description", "OS",
			"Status",
			"Owner", "Last Change",
		})
	}

	modifiedStr := humanize.Time(server.ChangeInfo.ModifiedDate)
	/* The ModifiedBy field can be an email address, or an API Key (hex string) */
	if _, err := hex.DecodeString(server.ChangeInfo.ModifiedBy); err == nil {
		modifiedStr += " via API Key"
	} else if len(server.ChangeInfo.ModifiedBy) > 6 {
		modifiedStr += " by " + server.ChangeInfo.ModifiedBy[:6]
	} else {
		modifiedStr += " by " + server.ChangeInfo.ModifiedBy
	}

	if server.Status == "active" {
		table.Append([]string{
			server.Name, grp.Name, server.Description, server.OsType,
			fmt.Sprint(server.Details.Cpu), fmt.Sprintf("%d G", server.Details.MemoryMb/1024), strings.Join(IPs, " "), server.Details.PowerState,
			modifiedStr,
		})
	} else {
		table.Append([]string{
			server.Name, grp.Name, server.Description, server.OsType,
			server.Status,
			server.ChangeInfo.CreatedBy, modifiedStr,
		})
	}
	table.Render()

	// Disks
	if len(server.Details.Disks) > 0 {
		fmt.Printf("\nDisks of %s (total storage: %d GB)\n", server.Name, server.Details.StorageGb)
		table = tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_RIGHT)
		table.SetAutoWrapText(true)

		table.SetHeader([]string{"Disk ID", "Disk Size/GB", "Paths"})
		for _, d := range server.Details.Disks {
			table.Append([]string{d.Id, fmt.Sprint(d.SizeGB), strings.Join(d.PartitionPaths, ", ")})
		}
		table.Render()
	}

	// Partitions
	if len(server.Details.Partitions) > 0 {
		fmt.Printf("\nPartitions of %s:\n", server.Name)
		table = tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_RIGHT)
		table.SetAutoWrapText(true)

		table.SetHeader([]string{"Partition Path", "Partition Size/GB"})
		for _, p := range server.Details.Partitions {
			table.Append([]string{p.Path, fmt.Sprintf("%.1f", p.SizeGB)})
		}
		table.Render()
	}

	// Snapshots
	if len(server.Details.Snapshots) > 0 {
		fmt.Println()

		table = tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)
		table.SetAlignment(tablewriter.ALIGN_CENTRE)
		table.SetAutoWrapText(true)

		table.SetHeader([]string{fmt.Sprintf("Snapshots of %s", server.Name)})
		for _, s := range server.Details.Snapshots {
			table.Append([]string{s.Name})
		}
		table.Render()
	}
}