JSON support for taking in host list (#8)

* Bumping up the version.

* Adding flags to take in JSON from the command line.

* go.sum no longer strictly necessary since go1.13

* Adding support for reading JSON list of hosts to drain from STDIN or from a file.

* Adding changes to changelogs
This commit is contained in:
Renan I. Del Valle 2020-02-07 18:41:59 -08:00 committed by GitHub
parent d63c719cef
commit f94a055b47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 91 additions and 93 deletions

View file

@ -189,7 +189,7 @@ func createJob(cmd *cobra.Command, args []string) {
log.Fatal("unable to create Aurora job: ", err)
}
if ok, monitorErr := client.InstancesMonitor(auroraJob.JobKey(),
if ok, monitorErr := client.MonitorInstances(auroraJob.JobKey(),
auroraJob.GetInstanceCount(),
5,
50); !ok || monitorErr != nil {

View file

@ -58,7 +58,7 @@ func killJob(cmd *cobra.Command, args []string) {
log.Fatalln(err)
}
if ok, err := client.InstancesMonitor(job.JobKey(), 0, 5, 50); !ok || err != nil {
if ok, err := client.MonitorInstances(job.JobKey(), 0, 5, 50); !ok || err != nil {
log.Fatalln("Unable to kill all instances of job")
}
}

View file

@ -61,7 +61,7 @@ func monitorHost(cmd *cobra.Command, args []string) {
}
log.Infof("Monitoring for %v at %v intervals", monitorHostCmd.monitorTimeout, monitorHostCmd.monitorInterval)
hostResult, err := client.HostMaintenanceMonitor(args, maintenanceModes, monitorHostCmd.monitorInterval, monitorHostCmd.monitorTimeout)
hostResult, err := client.MonitorHostMaintenance(args, maintenanceModes, monitorHostCmd.monitorInterval, monitorHostCmd.monitorTimeout)
maintenanceMonitorPrint(hostResult, maintenanceModes)

View file

@ -36,7 +36,7 @@ var pulseJobUpdateCmd = &cobra.Command{
func pulseJobUpdate(cmd *cobra.Command, args []string) {
_, err := client.PulseJobUpdate(
&aurora.JobUpdateKey{
aurora.JobUpdateKey{
Job: &aurora.JobKey{Environment: *env, Role: *role, Name: *name},
ID: updateID,
})

View file

@ -37,7 +37,7 @@ var resumeJobUpdateCmd = &cobra.Command{
func resumeJobUpdate(cmd *cobra.Command, args []string) {
err := client.ResumeJobUpdate(
&aurora.JobUpdateKey{
aurora.JobUpdateKey{
Job: &aurora.JobKey{Environment: *env, Role: *role, Name: *name},
ID: updateID,
},

View file

@ -36,6 +36,8 @@ var caCertsPath string
var clientKey, clientCert string
var configFile string
var toJson bool
var fromJson bool
var fromJsonFile string
var logLevel string
var duration time.Duration
var percent float64
@ -43,10 +45,9 @@ var count int64
var filename string
var message = new(string)
var updateID string
var statusList = make([]string, 0, 0)
var log = logrus.New()
const australisVer = "v0.0.10"
const australisVer = "v0.1.0"
var forceDrainTimeout time.Duration

View file

@ -15,6 +15,10 @@
package cmd
import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"time"
"github.com/paypal/gorealis/v2/gen-go/apache/aurora"
@ -23,6 +27,8 @@ import (
const countFlag = "count"
const percentageFlag = "percentage"
const jsonFlag = "json"
const jsonFileFlag = "json-file"
func init() {
rootCmd.AddCommand(startCmd)
@ -34,6 +40,8 @@ func init() {
// Maintenance specific flags
startDrainCmd.cmd.Flags().DurationVar(&startDrainCmd.monitorInterval, "interval", time.Second*5, "Interval at which to poll scheduler.")
startDrainCmd.cmd.Flags().DurationVar(&startDrainCmd.monitorTimeout, "timeout", time.Minute*10, "Time after which the monitor will stop polling and throw an error.")
startDrainCmd.cmd.Flags().StringVar(&fromJsonFile, jsonFileFlag, "", "JSON file to read list of agents from.")
startDrainCmd.cmd.Flags().BoolVar(&fromJson, jsonFlag, false, "Read JSON list of agents from the STDIN.")
/* SLA Aware commands */
startCmd.AddCommand(startSLADrainCmd.cmd)
@ -46,6 +54,8 @@ func init() {
startSLADrainCmd.cmd.Flags().DurationVar(&forceDrainTimeout, "sla-limit", time.Minute*60, "Time limit after which SLA-Aware drain sheds SLA Awareness.")
startSLADrainCmd.cmd.Flags().DurationVar(&startSLADrainCmd.monitorInterval, "interval", time.Second*10, "Interval at which to poll scheduler.")
startSLADrainCmd.cmd.Flags().DurationVar(&startSLADrainCmd.monitorTimeout, "timeout", time.Minute*20, "Time after which the monitor will stop polling and throw an error.")
startSLADrainCmd.cmd.Flags().StringVar(&fromJsonFile, jsonFileFlag, "", "JSON file to read list of agents from.")
startSLADrainCmd.cmd.Flags().BoolVar(&fromJson, jsonFlag, false, "Read JSON list of agents from the STDIN.")
startCmd.AddCommand(startMaintenanceCmd.cmd)
startMaintenanceCmd.cmd.Run = maintenance
@ -53,6 +63,8 @@ func init() {
// SLA Maintenance specific flags
startMaintenanceCmd.cmd.Flags().DurationVar(&startMaintenanceCmd.monitorInterval, "interval", time.Second*5, "Interval at which to poll scheduler.")
startMaintenanceCmd.cmd.Flags().DurationVar(&startMaintenanceCmd.monitorTimeout, "timeout", time.Minute*10, "Time after which the monitor will stop polling and throw an error.")
startMaintenanceCmd.cmd.Flags().StringVar(&fromJsonFile, jsonFileFlag, "", "JSON file to read list of agents from.")
startMaintenanceCmd.cmd.Flags().BoolVar(&fromJson, jsonFlag, false, "Read JSON list of agents from the STDIN.")
}
var startCmd = &cobra.Command{
@ -62,19 +74,19 @@ var startCmd = &cobra.Command{
var startDrainCmd = monitorCmdConfig{
cmd: &cobra.Command{
Use: "drain [space separated host list]",
Use: "drain [space separated host list or use JSON flags]",
Short: "Place a list of space separated Mesos Agents into draining mode.",
Long: `Adds a Mesos Agent to Aurora's Drain list. Agents in this list
are not allowed to schedule new tasks and any tasks already running on this Agent
are killed and rescheduled in an Agent that is not in maintenance mode. Command
expects a space separated list of hosts to place into maintenance mode.`,
Args: cobra.MinimumNArgs(1),
Args: argsValidateJSONFlags,
},
}
var startSLADrainCmd = monitorCmdConfig{
cmd: &cobra.Command{
Use: "sla-drain [space separated host list]",
Use: "sla-drain [space separated host list or use JSON flags]",
Short: "Place a list of space separated Mesos Agents into maintenance mode using SLA aware strategies.",
Long: `Adds a Mesos Agent to Aurora's Drain list. Agents in this list
are not allowed to schedule new tasks and any tasks already running on this Agent
@ -84,25 +96,66 @@ If the --count argument is passed, tasks will be drained using the count SLA pol
when a Job does not have a defined SLA policy.
If the --percentage argument is passed, tasks will be drained using the percentage SLA policy as a fallback
when a Job does not have a defined SLA policy.`,
Args: cobra.MinimumNArgs(1),
Args: argsValidateJSONFlags,
},
}
var startMaintenanceCmd = monitorCmdConfig{
cmd: &cobra.Command{
Use: "maintenance [space separated host list]",
Use: "maintenance [space separated host list or use JSON flags]",
Short: "Place a list of space separated Mesos Agents into maintenance mode.",
Long: `Places Mesos Agent into Maintenance mode. Agents in this list
are de-prioritized for scheduling a task. Command
expects a space separated list of hosts to place into maintenance mode.`,
Args: cobra.MinimumNArgs(1),
Args: argsValidateJSONFlags,
},
}
func argsValidateJSONFlags(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed(jsonFlag) && cmd.Flags().Changed(jsonFileFlag) {
return errors.New("only json file or json stdin must be set")
}
// These two flags are mutually exclusive
if cmd.Flags().Changed(jsonFlag) != cmd.Flags().Changed(jsonFileFlag) {
return nil
}
if len(args) < 1 {
return errors.New("at least one host must be specified")
}
return nil
}
func hostList(cmd *cobra.Command, args []string) []string {
var hosts []string
if cmd.Flags().Changed(jsonFlag) {
err := json.NewDecoder(os.Stdin).Decode(&hosts)
if err != nil {
log.Fatal(err)
}
} else if cmd.Flags().Changed(jsonFileFlag) {
data, err := ioutil.ReadFile(fromJsonFile)
if err != nil {
log.Fatal(err)
}
err = json.Unmarshal(data, &hosts)
if err != nil {
log.Fatal(err)
}
} else {
hosts = args
}
return hosts
}
func drain(cmd *cobra.Command, args []string) {
hosts := hostList(cmd, args)
log.Infoln("Setting hosts to DRAINING")
log.Infoln(args)
result, err := client.DrainHosts(args...)
log.Infoln(hosts)
result, err := client.DrainHosts(hosts...)
if err != nil {
log.Fatalf("error: %+v", err)
}
@ -111,8 +164,8 @@ func drain(cmd *cobra.Command, args []string) {
log.Infof("Monitoring for %v at %v intervals", monitorHostCmd.monitorTimeout, monitorHostCmd.monitorInterval)
// Monitor change to DRAINING and DRAINED mode
hostResult, err := client.HostMaintenanceMonitor(
args,
hostResult, err := client.MonitorHostMaintenance(
hosts,
[]aurora.MaintenanceMode{aurora.MaintenanceMode_DRAINED},
startDrainCmd.monitorInterval,
startDrainCmd.monitorTimeout)
@ -125,7 +178,6 @@ func drain(cmd *cobra.Command, args []string) {
}
func slaDrainHosts(policy *aurora.SlaPolicy, interval, timeout time.Duration, hosts ...string) {
result, err := client.SLADrainHosts(policy, int64(forceDrainTimeout.Seconds()), hosts...)
if err != nil {
log.Fatalf("error: %+v\n", err)
@ -135,7 +187,7 @@ func slaDrainHosts(policy *aurora.SlaPolicy, interval, timeout time.Duration, ho
log.Infof("Monitoring for %v at %v intervals", timeout, interval)
// Monitor change to DRAINING and DRAINED mode
hostResult, err := client.HostMaintenanceMonitor(
hostResult, err := client.MonitorHostMaintenance(
hosts,
[]aurora.MaintenanceMode{aurora.MaintenanceMode_DRAINED},
interval,
@ -148,6 +200,8 @@ func slaDrainHosts(policy *aurora.SlaPolicy, interval, timeout time.Duration, ho
}
}
func slaDrain(cmd *cobra.Command, args []string) {
hosts := hostList(cmd, args)
// This check makes sure only a single flag is set.
// If they're both set or both not set, the statement will evaluate to true.
if cmd.Flags().Changed(percentageFlag) == cmd.Flags().Changed(countFlag) {
@ -170,15 +224,17 @@ func slaDrain(cmd *cobra.Command, args []string) {
}
log.Infoln("Hosts affected: ", args)
slaDrainHosts(policy, startDrainCmd.monitorInterval, startDrainCmd.monitorTimeout, args...)
slaDrainHosts(policy, startDrainCmd.monitorInterval, startDrainCmd.monitorTimeout, hosts...)
}
func maintenance(cmd *cobra.Command, args []string) {
hosts := hostList(cmd, args)
log.Infoln("Setting hosts to Maintenance mode")
log.Infoln(args)
result, err := client.StartMaintenance(args...)
log.Infoln(hosts)
result, err := client.StartMaintenance(hosts...)
if err != nil {
log.Fatalf("error: %+v\n", err)
log.Fatalf("error: %+v", err)
}
log.Debugln(result)
@ -186,8 +242,8 @@ func maintenance(cmd *cobra.Command, args []string) {
log.Infof("Monitoring for %v at %v intervals", monitorHostCmd.monitorTimeout, monitorHostCmd.monitorInterval)
// Monitor change to DRAINING and DRAINED mode
hostResult, err := client.HostMaintenanceMonitor(
args,
hostResult, err := client.MonitorHostMaintenance(
hosts,
[]aurora.MaintenanceMode{aurora.MaintenanceMode_SCHEDULED},
startMaintenanceCmd.monitorInterval,
startMaintenanceCmd.monitorTimeout)

View file

@ -66,13 +66,13 @@ func endMaintenance(cmd *cobra.Command, args []string) {
log.Println(args)
result, err := client.EndMaintenance(args...)
if err != nil {
log.Fatalf("error: %+v\n", err)
log.Fatalf("error: %+v", err)
}
log.Debugln(result)
// Monitor change to NONE mode
hostResult, err := client.HostMaintenanceMonitor(
hostResult, err := client.MonitorHostMaintenance(
args,
[]aurora.MaintenanceMode{aurora.MaintenanceMode_NONE},
stopMaintenanceConfig.monitorInterval,