github.com/fafucoder/cilium@v1.6.11/cilium/cmd/service_list.go (about) 1 // Copyright 2017 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cmd 16 17 import ( 18 "fmt" 19 "os" 20 "sort" 21 "text/tabwriter" 22 23 "github.com/cilium/cilium/api/v1/models" 24 "github.com/cilium/cilium/pkg/command" 25 "github.com/cilium/cilium/pkg/loadbalancer" 26 27 "github.com/spf13/cobra" 28 ) 29 30 // serviceListCmd represents the service_list command 31 var serviceListCmd = &cobra.Command{ 32 Use: "list", 33 Aliases: []string{"ls"}, 34 Short: "List services", 35 Run: func(cmd *cobra.Command, args []string) { 36 listServices(cmd, args) 37 }, 38 } 39 40 func init() { 41 serviceCmd.AddCommand(serviceListCmd) 42 command.AddJSONOutput(serviceListCmd) 43 } 44 45 func listServices(cmd *cobra.Command, args []string) { 46 list, err := client.GetServices() 47 if err != nil { 48 Fatalf("Cannot get services list: %s", err) 49 } 50 51 if command.OutputJSON() { 52 if err := command.PrintOutput(list); err != nil { 53 os.Exit(1) 54 } 55 return 56 } 57 58 w := tabwriter.NewWriter(os.Stdout, 5, 0, 3, ' ', 0) 59 printServiceList(w, list) 60 } 61 62 func printServiceList(w *tabwriter.Writer, list []*models.Service) { 63 fmt.Fprintln(w, "ID\tFrontend\tBackend\t") 64 65 type ServiceOutput struct { 66 ID int64 67 FrontendAddress string 68 BackendAddresses []string 69 } 70 svcs := []ServiceOutput{} 71 72 for _, svc := range list { 73 if svc.Status == nil || svc.Status.Realized == nil { 74 fmt.Fprint(os.Stderr, "error parsing svc: empty state") 75 continue 76 } 77 78 feA, err := loadbalancer.NewL3n4AddrFromModel(svc.Status.Realized.FrontendAddress) 79 if err != nil { 80 fmt.Fprintf(os.Stderr, "error parsing frontend %+v", svc.Status.Realized.FrontendAddress) 81 continue 82 } 83 84 var backendAddresses []string 85 for i, be := range svc.Status.Realized.BackendAddresses { 86 beA, err := loadbalancer.NewL3n4AddrFromBackendModel(be) 87 if err != nil { 88 fmt.Fprintf(os.Stderr, "error parsing backend %+v", be) 89 continue 90 } 91 var str string 92 if be.Weight != 0 { 93 str = fmt.Sprintf("%d => %s (W: %d)", i+1, beA.String(), be.Weight) 94 } else { 95 str = fmt.Sprintf("%d => %s", i+1, beA.String()) 96 } 97 backendAddresses = append(backendAddresses, str) 98 } 99 100 SvcOutput := ServiceOutput{ 101 ID: svc.Status.Realized.ID, 102 FrontendAddress: feA.String(), 103 BackendAddresses: backendAddresses, 104 } 105 svcs = append(svcs, SvcOutput) 106 } 107 108 sort.Slice(svcs, func(i, j int) bool { 109 return svcs[i].ID <= svcs[j].ID 110 }) 111 112 for _, service := range svcs { 113 var str string 114 115 if len(service.BackendAddresses) == 0 { 116 str = fmt.Sprintf("%d\t%s\t\t", 117 service.ID, service.FrontendAddress) 118 fmt.Fprintln(w, str) 119 continue 120 } 121 122 str = fmt.Sprintf("%d\t%s\t%s\t", 123 service.ID, service.FrontendAddress, 124 service.BackendAddresses[0]) 125 fmt.Fprintln(w, str) 126 127 for _, bkaddr := range service.BackendAddresses[1:] { 128 str := fmt.Sprintf("\t\t%s\t", bkaddr) 129 fmt.Fprintln(w, str) 130 } 131 } 132 133 w.Flush() 134 }