github.com/kolanos/fargate@v0.2.3/cmd/service_info.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sort"
     7  	"strings"
     8  	"text/tabwriter"
     9  
    10  	ACM "github.com/jpignata/fargate/acm"
    11  	"github.com/jpignata/fargate/console"
    12  	EC2 "github.com/jpignata/fargate/ec2"
    13  	ECS "github.com/jpignata/fargate/ecs"
    14  	ELBV2 "github.com/jpignata/fargate/elbv2"
    15  	"github.com/jpignata/fargate/util"
    16  	"github.com/spf13/cobra"
    17  )
    18  
    19  const statusActive = "ACTIVE"
    20  
    21  type ServiceInfoOperation struct {
    22  	ServiceName string
    23  }
    24  
    25  var serviceInfoCmd = &cobra.Command{
    26  	Use:   "info <service-name>",
    27  	Short: "Inspect service",
    28  	Long: `Inspect service
    29  
    30  Show extended information for a service including load balancer configuration,
    31  active deployments, and environment variables.
    32  
    33  Deployments show active versions of your service that are running. Multiple
    34  deployments are shown if a service is transitioning due to a deployment or
    35  update to configuration such a CPU, memory, or environment variables.`,
    36  	Args: cobra.ExactArgs(1),
    37  	Run: func(cmd *cobra.Command, args []string) {
    38  		operation := &ServiceInfoOperation{
    39  			ServiceName: args[0],
    40  		}
    41  
    42  		getServiceInfo(operation)
    43  	},
    44  }
    45  
    46  func init() {
    47  	serviceCmd.AddCommand(serviceInfoCmd)
    48  }
    49  
    50  func getServiceInfo(operation *ServiceInfoOperation) {
    51  	var eniIds []string
    52  
    53  	acm := ACM.New(sess)
    54  	ecs := ECS.New(sess, clusterName)
    55  	ec2 := EC2.New(sess)
    56  	elbv2 := ELBV2.New(sess)
    57  	service := ecs.DescribeService(operation.ServiceName)
    58  	tasks := ecs.DescribeTasksForService(operation.ServiceName)
    59  
    60  	if service.Status != statusActive {
    61  		console.InfoExit("Service not found")
    62  	}
    63  
    64  	console.KeyValue("Service Name", "%s\n", operation.ServiceName)
    65  	console.KeyValue("Status", "\n")
    66  	console.KeyValue("  Desired", "%d\n", service.DesiredCount)
    67  	console.KeyValue("  Running", "%d\n", service.RunningCount)
    68  	console.KeyValue("  Pending", "%d\n", service.PendingCount)
    69  	console.KeyValue("Image", "%s\n", service.Image)
    70  	console.KeyValue("Cpu", "%s\n", service.Cpu)
    71  	console.KeyValue("Memory", "%s\n", service.Memory)
    72  
    73  	if service.TaskRole != "" {
    74  		console.KeyValue("Task Role", "%s\n", service.TaskRole)
    75  	}
    76  
    77  	console.KeyValue("Subnets", "%s\n", strings.Join(service.SubnetIds, ", "))
    78  	console.KeyValue("Security Groups", "%s\n", strings.Join(service.SecurityGroupIds, ", "))
    79  
    80  	if service.TargetGroupArn != "" {
    81  		if loadBalancerArn := elbv2.GetTargetGroupLoadBalancerArn(service.TargetGroupArn); loadBalancerArn != "" {
    82  			loadBalancer := elbv2.DescribeLoadBalancerByArn(loadBalancerArn)
    83  			listeners := elbv2.GetListeners(loadBalancerArn)
    84  
    85  			console.KeyValue("Load Balancer", "\n")
    86  			console.KeyValue("  Name", "%s\n", loadBalancer.Name)
    87  			console.KeyValue("  DNS Name", "%s\n", loadBalancer.DNSName)
    88  
    89  			if len(listeners) > 0 {
    90  				console.KeyValue("  Ports", "\n")
    91  			}
    92  
    93  			for _, listener := range listeners {
    94  				var ruleOutput []string
    95  
    96  				rules := elbv2.DescribeRules(listener.Arn)
    97  
    98  				sort.Slice(rules, func(i, j int) bool { return rules[i].Priority > rules[j].Priority })
    99  
   100  				for _, rule := range rules {
   101  					if rule.TargetGroupArn == service.TargetGroupArn {
   102  						ruleOutput = append(ruleOutput, rule.String())
   103  					}
   104  				}
   105  
   106  				console.KeyValue("    "+listener.String(), "\n")
   107  				console.KeyValue("      Rules", "%s\n", strings.Join(ruleOutput, ", "))
   108  
   109  				if len(listener.CertificateArns) > 0 {
   110  					certificateDomains := acm.ListCertificateDomainNames(listener.CertificateArns)
   111  					console.KeyValue("      Certificates", "%s\n", strings.Join(certificateDomains, ", "))
   112  				}
   113  			}
   114  		}
   115  
   116  		if len(service.EnvVars) > 0 {
   117  			console.KeyValue("Environment Variables", "\n")
   118  
   119  			for _, envVar := range service.EnvVars {
   120  				fmt.Printf("   %s=%s\n", envVar.Key, envVar.Value)
   121  			}
   122  		}
   123  	}
   124  
   125  	if len(tasks) > 0 {
   126  		console.Header("Tasks")
   127  
   128  		for _, task := range tasks {
   129  			if task.EniId != "" {
   130  				eniIds = append(eniIds, task.EniId)
   131  			}
   132  		}
   133  
   134  		enis := ec2.DescribeNetworkInterfaces(eniIds)
   135  		w := new(tabwriter.Writer)
   136  
   137  		w.Init(os.Stdout, 0, 8, 1, '\t', 0)
   138  		fmt.Fprintln(w, "ID\tIMAGE\tSTATUS\tRUNNING\tIP\tCPU\tMEMORY\tDEPLOYMENT\t")
   139  
   140  		for _, t := range tasks {
   141  			fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
   142  				t.TaskId,
   143  				t.Image,
   144  				util.Humanize(t.LastStatus),
   145  				t.RunningFor(),
   146  				enis[t.EniId].PublicIpAddress,
   147  				t.Cpu,
   148  				t.Memory,
   149  				t.DeploymentId,
   150  			)
   151  		}
   152  
   153  		w.Flush()
   154  	}
   155  
   156  	if len(service.Deployments) > 0 {
   157  		console.Header("Deployments")
   158  
   159  		w := new(tabwriter.Writer)
   160  		w.Init(os.Stdout, 0, 8, 1, '\t', 0)
   161  		fmt.Fprintln(w, "ID\tIMAGE\tSTATUS\tCREATED\tDESIRED\tRUNNING\tPENDING")
   162  
   163  		for _, d := range service.Deployments {
   164  			fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\t%d\t%d\n",
   165  				d.Id,
   166  				d.Image,
   167  				util.Humanize(d.Status),
   168  				d.CreatedAt,
   169  				d.DesiredCount,
   170  				d.RunningCount,
   171  				d.PendingCount,
   172  			)
   173  		}
   174  
   175  		w.Flush()
   176  	}
   177  
   178  	if len(service.Events) > 0 {
   179  		console.Header("Events")
   180  
   181  		for i, event := range service.Events {
   182  			fmt.Printf("[%s] %s\n", event.CreatedAt, event.Message)
   183  
   184  			if i == 10 && !verbose {
   185  				break
   186  			}
   187  		}
   188  	}
   189  }