github.com/scaleway/scaleway-cli@v1.11.1/pkg/commands/ps.go (about) 1 // Copyright (C) 2015 Scaleway. All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE.md file. 4 5 package commands 6 7 import ( 8 "fmt" 9 "sort" 10 "strings" 11 "text/tabwriter" 12 "time" 13 14 "github.com/Sirupsen/logrus" 15 "github.com/docker/go-units" 16 "github.com/renstrom/fuzzysearch/fuzzy" 17 18 "github.com/scaleway/scaleway-cli/pkg/api" 19 "github.com/scaleway/scaleway-cli/pkg/utils" 20 ) 21 22 // PsArgs are flags for the `RunPs` function 23 type PsArgs struct { 24 NLast int 25 All bool 26 Latest bool 27 NoTrunc bool 28 Quiet bool 29 Filters map[string]string 30 } 31 32 // RunPs is the handler for 'scw ps' 33 func RunPs(ctx CommandContext, args PsArgs) error { 34 limit := args.NLast 35 if args.Latest { 36 limit = 1 37 } 38 39 filterState := args.Filters["state"] 40 41 // FIXME: if filter state is defined, try to optimize the query 42 all := args.All || limit > 0 || filterState != "" 43 servers, err := ctx.API.GetServers(all, 0) 44 if err != nil { 45 return fmt.Errorf("Unable to fetch servers from the Scaleway API: %v", err) 46 } 47 48 for key, value := range args.Filters { 49 switch key { 50 case "state", "name", "tags", "image", "ip", "arch", "server-type", "zone": 51 continue 52 default: 53 logrus.Warnf("Unknown filter: '%s=%s'", key, value) 54 } 55 } 56 filtered := make([]api.ScalewayServer, 0, len(*servers)) 57 for _, server := range *servers { 58 // filtering 59 for key, value := range args.Filters { 60 switch key { 61 case "state": 62 if value != server.State { 63 goto skipServer 64 } 65 case "name": 66 if fuzzy.RankMatch(strings.ToLower(value), strings.ToLower(server.Name)) == -1 { 67 goto skipServer 68 } 69 case "tags": 70 found := false 71 for _, tag := range server.Tags { 72 if tag == value { 73 found = true 74 continue 75 } 76 } 77 if !found { 78 goto skipServer 79 } 80 case "image": 81 imageID, err := ctx.API.GetImageID(value, "*") 82 if err != nil { 83 goto skipServer 84 } 85 if imageID.Identifier != server.Image.Identifier { 86 goto skipServer 87 } 88 case "ip": 89 if value != server.PublicAddress.IP { 90 goto skipServer 91 } 92 case "arch": 93 if value != server.Arch { 94 goto skipServer 95 } 96 case "server-type": 97 if value != server.CommercialType { 98 goto skipServer 99 } 100 case "zone": 101 if value != server.Location.ZoneID { 102 goto skipServer 103 } 104 } 105 } 106 filtered = append(filtered, server) 107 skipServer: 108 continue 109 } 110 w := tabwriter.NewWriter(ctx.Stdout, 20, 1, 3, ' ', 0) 111 defer w.Flush() 112 if !args.Quiet { 113 fmt.Fprintf(w, "SERVER ID\tIMAGE\tZONE\tCREATED\tSTATUS\tPORTS\tNAME\tCOMMERCIAL TYPE\n") 114 } 115 sort.Sort(api.ScalewaySortServers(filtered)) 116 for i, server := range filtered { 117 if limit > 0 && i >= limit { 118 break 119 } 120 if args.Quiet { 121 fmt.Fprintf(w, "%s\n", server.Identifier) 122 } else { 123 shortID := utils.TruncIf(server.Identifier, 8, !args.NoTrunc) 124 shortImage := utils.TruncIf(utils.Wordify(server.Image.Name), 25, !args.NoTrunc) 125 shortName := utils.TruncIf(utils.Wordify(server.Name), 25, !args.NoTrunc) 126 creationTime, _ := time.Parse("2006-01-02T15:04:05.000000+00:00", server.CreationDate) 127 shortCreationDate := units.HumanDuration(time.Now().UTC().Sub(creationTime)) 128 port := server.PublicAddress.IP 129 fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", shortID, shortImage, server.Location.ZoneID, shortCreationDate, server.State, port, shortName, server.CommercialType) 130 } 131 } 132 return nil 133 }