Ejemplo n.º 1
0
func doHistory(c *cli.Context) {
	if len(c.Args()) == 0 {
		displayWrongNumOfArgsAndExit(c)
	}
	vename := c.Args().Get(0)

	path := "/ve/" + vename + "/history/"
	if len(c.String("from")) > 0 && len(c.String("to")) > 0 {
		_, err := lib.ParseArgTimestampFormat(c.String("from"))
		assert(err, "'from' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

		_, err = lib.ParseArgTimestampFormat(c.String("to"))
		assert(err, "'to' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

		path += c.String("from") + "/" + c.String("to")
	} else if c.Int("num-records") > 0 {
		path += strconv.Itoa(c.Int("num-records"))
	} else {
		displayErrorAndExit("This command must be used with a pair of --from and --to flags arguments or --num-records flag argument. Please see '" + c.App.Name + " help " + c.Command.Name + "'")
	}

	resp, err := client.SendRequest("GET", path, nil)
	assert(err)
	if resp.StatusCode >= 400 {
		displayErrorAndExit(string(resp.Body))
	}

	hst := lib.VeHistory{}
	assert(xml.Unmarshal(resp.Body, &hst))
	assert(err)

	outputResult(c, hst, func(format string) {
		if c.Bool("verbose") {
			lib.PrintXMLStruct(hst)
		} else {
			tbl, err := prettytable.NewTable([]prettytable.Column{
				{Header: "DATETIME"},
				{Header: "CPU", AlignRight: true},
				{Header: "MEMORY", AlignRight: true},
				{Header: "DISK", AlignRight: true},
				{Header: "BANDWIDTH", AlignRight: true},
				{Header: "PUB_IPS", AlignRight: true},
				{Header: "STATUS"},
			}...)
			assert(err)
			if c.Bool("no-header") {
				tbl.NoHeader = true
			}
			for _, e := range hst.VeSnapshot {
				ts, _ := e.EventTimestamp.MarshalText()
				tbl.AddRow(ts, e.CPU, e.RAM, e.LocalDisk, e.Bandwidth, e.NoOfPublicIP, e.State)
			}
			tbl.Print()
		}
	})
}
Ejemplo n.º 2
0
func doUsage(c *cli.Context) {
	if len(c.Args()) == 0 {
		displayWrongNumOfArgsAndExit(c)
	}
	vename := c.Args().Get(0)

	if len(c.String("from")) == 0 || len(c.String("to")) == 0 {
		displayErrorAndExit("This command must be used with a pair of --from and --to flags arguments. Please see '" + c.App.Name + " help " + c.Command.Name + "'")
	}
	path := "/ve/" + vename + "/usage/"

	from, err := lib.ParseArgTimestampFormat(c.String("from"))
	assert(err, "'from' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

	to, err := lib.ParseArgTimestampFormat(c.String("to"))
	assert(err, "'to' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

	path += c.String("from") + "/" + c.String("to")

	resp, err := client.SendRequest("GET", path, nil)
	assert(err)
	if resp.StatusCode >= 400 {
		displayErrorAndExit(string(resp.Body))
	}

	usage := lib.VeResourceUsageReport{}
	assert(xml.Unmarshal(resp.Body, &usage))

	outputResult(c, usage, func(format string) {
		if c.Bool("verbose") {
			lib.PrintXMLStruct(usage)
		} else {
			fmt.Println("RESOURCE USAGE REPORT")
			fmt.Printf("Server: %s\n", usage.VeName)
			fmt.Printf("  From: %s\n", from.Format(lib.DataTimestampFormat))
			fmt.Printf("    To: %s\n\n", to.Format(lib.DataTimestampFormat))

			tbl, err := prettytable.NewTable([]prettytable.Column{
				{Header: "RESOURCE_TYPE"}, {Header: "USAGE", AlignRight: true},
			}...)
			assert(err)
			for _, e := range usage.ResourceUsage {
				name := e.ResourceType
				if len(e.ResourceUsageType) > 0 {
					name += "(" + e.ResourceUsageType + ")"
				}
				tbl.AddRow(name, e.Value)
			}
			for _, e := range usage.VeTraffic {
				tbl.AddRow(e.TrafficType, e.Used)
			}
			tbl.Print()
		}
	})
}
Ejemplo n.º 3
0
func doBackupList(c *cli.Context) {
	if len(c.Args()) == 0 {
		displayWrongNumOfArgsAndExit(c)
	}
	vename := c.Args().Get(0)

	if len(c.String("from")) == 0 || len(c.String("to")) == 0 {
		displayErrorAndExit("This command must be used with a pair of --from and --to flags arguments. Please see '" + c.App.Name + " help " + c.Command.Name + "'")
	}
	path := "/ve/" + vename + "/backups/"

	from, err := lib.ParseArgTimestampFormat(c.String("from"))
	assert(err, "'from' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

	to, err := lib.ParseArgTimestampFormat(c.String("to"))
	assert(err, "'to' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

	path += c.String("from") + "/" + c.String("to")

	resp, err := client.SendRequest("GET", path, nil)
	assert(err)
	if resp.StatusCode >= 400 {
		displayErrorAndExit(string(resp.Body))
	}

	backups := lib.VeBackups{}
	assert(xml.Unmarshal(resp.Body, &backups))

	outputResult(c, backups, func(format string) {
		if c.Bool("verbose") {
			lib.PrintXMLStruct(backups)
		} else {
			fmt.Println("BACKUP LIST")
			fmt.Printf("Server: %s\n", vename)
			fmt.Printf("  From: %s\n", from.Format(lib.DataTimestampFormat))
			fmt.Printf("    To: %s\n\n", to.Format(lib.DataTimestampFormat))

			tbl, err := prettytable.NewTable([]prettytable.Column{
				{Header: "ID"},
				{Header: "SCHEDULE"},
				{Header: "START"},
				{Header: "END"},
				{Header: "RESULT", AlignRight: true},
				{Header: "SIZE(GB)", AlignRight: true},
				{Header: "NODE"},
				{Header: "DESCRIPTION"},
			}...)
			assert(err)
			for _, e := range backups.Backup {
				schedule := "-"
				if len(e.ScheduleName) > 0 {
					schedule = e.ScheduleName
				}
				result := "fail"
				if e.Successful == true {
					result = "ok"
				}
				size := strconv.FormatFloat(float64(e.BackupSize)/(1<<30), 'f', 3, 64)
				tbl.AddRow(e.CloudBackupID, schedule, e.Started, e.Ended, result, size, e.BackupNodeName, e.Description)
			}
			tbl.Print()
		}
	})
}
Ejemplo n.º 4
0
func doAutoscaleHistory(c *cli.Context) {
	if len(c.Args()) == 0 {
		displayWrongNumOfArgsAndExit(c)
	}
	vename := c.Args().Get(0)

	path := "/ve/" + vename + "/autoscale/history/"
	if len(c.String("from")) > 0 && len(c.String("to")) > 0 {
		_, err := lib.ParseArgTimestampFormat(c.String("from"))
		assert(err, "'from' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

		_, err = lib.ParseArgTimestampFormat(c.String("to"))
		assert(err, "'to' arg value must be in "+lib.ArgTimestampFormatStr()+" format")

		path += c.String("from") + "/" + c.String("to")
		var q []string
		if c.Int("average-period") > 0 {
			q = append(q, "average-period="+strconv.Itoa(c.Int("average-period")))
		}
		if c.Int("tail") > 0 {
			q = append(q, "tail="+strconv.Itoa(c.Int("tail")))
		}
		if len(q) > 0 {
			path += "?" + strings.Join(q, "&")
		}
	} else if c.Int("num-records") > 0 {
		path += strconv.Itoa(c.Int("num-records"))
	} else {
		displayErrorAndExit("This command must be used with a pair of --from and --to flags arguments or --num-records flag argument. Please see '" + c.App.Name + " help " + c.Command.Name + "'")
	}

	resp, err := client.SendRequest("GET", path, nil)
	assert(err)
	if resp.StatusCode >= 400 {
		displayErrorAndExit(string(resp.Body))
	}

	hst := lib.ResourceConsumptionAndAutoscaleHistory{}
	assert(xml.Unmarshal(resp.Body, &hst))
	assert(err)

	outputResult(c, hst, func(format string) {
		if c.Bool("verbose") {
			lib.PrintXMLStruct(hst)
		} else {
			if len(hst.AutoscaleRule) > 0 {
				fmt.Println("AUTOSCALE RULE HISTORY")
				tbl, err := prettytable.NewTable([]prettytable.Column{
					{Header: "METRIC"},
					{Header: "VERSION", AlignRight: true},
					{Header: "UPDATED"},
					{Header: "DELIVERED"},
					{Header: "DELIVERED-OK"},
					{Header: "MIGRATION"},
					{Header: "RESTART"},
					{Header: "MIN", AlignRight: true},
					{Header: "MAX", AlignRight: true},
					{Header: "STEP", AlignRight: true},
					{Header: "UP_THRES", AlignRight: true},
					{Header: "UP_PERIOD", AlignRight: true},
					{Header: "DOWN_THRES", AlignRight: true},
					{Header: "DOWN_PERIOD", AlignRight: true},
				}...)
				assert(err)
				if c.Bool("no-header") {
					tbl.NoHeader = true
				}
				for _, e := range hst.AutoscaleRule {
					tbl.AddRow(
						e.Metric,
						*e.Version,
						*e.Updated,
						*e.UpdateDelivered,
						*e.UpdateDeliveredOk,
						*e.AllowMigration,
						*e.AllowRestart,
						e.Limits.Min,
						e.Limits.Max,
						e.Limits.Step,
						*e.Thresholds.Up.Threshold,
						e.Thresholds.Up.Period,
						*e.Thresholds.Down.Threshold,
						e.Thresholds.Down.Period,
					)
				}
				tbl.Print()
				fmt.Println()
			}

			fmt.Println("RESOURCE CONSUMPTION")
			tbl, err := prettytable.NewTable([]prettytable.Column{
				{Header: "CPU_USAGE", AlignRight: true},
				{Header: "RAM_USAGE", AlignRight: true},
				{Header: "PRIV_IN", AlignRight: true},
				{Header: "PRIV_OUT", AlignRight: true},
				{Header: "PUB_IN", AlignRight: true},
				{Header: "PUB_OUT", AlignRight: true},
				{Header: "DATETIME"},
				{Header: "CPU", AlignRight: true},
				{Header: "RAM", AlignRight: true},
				{Header: "BANDWIDTH", AlignRight: true},
			}...)
			assert(err)
			if c.Bool("no-header") {
				tbl.NoHeader = true
			}
			for _, e := range hst.ResourceConsumptionSample {
				tbl.AddRow(
					e.CPUUsage,
					e.RAMUsage,
					e.PrivateIncomingTraffic,
					e.PrivateOutgoingTraffic,
					e.PublicIncomingTraffic,
					e.PublicOutgoingTraffic,
					e.PaciTimestamp,
					e.CPU,
					e.RAM,
					e.Bandwidth,
				)
			}
			tbl.Print()
		}
	})
}