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  }