github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/intercept/info.go (about) 1 package intercept 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net" 8 "strings" 9 10 "github.com/telepresenceio/telepresence/rpc/v2/manager" 11 "github.com/telepresenceio/telepresence/v2/pkg/client" 12 "github.com/telepresenceio/telepresence/v2/pkg/ioutil" 13 ) 14 15 type Ingress struct { 16 Host string `json:"host,omitempty" yaml:"host,omitempty"` 17 Port int32 `json:"port,omitempty" yaml:"port,omitempty"` 18 UseTLS bool `json:"use_tls,omitempty" yaml:"use_tls,omitempty"` 19 L5Host string `json:"l5host,omitempty" yaml:"l5host,omitempty"` 20 } 21 22 type Mount struct { 23 LocalDir string `json:"local_dir,omitempty" yaml:"local_dir,omitempty"` 24 RemoteDir string `json:"remote_dir,omitempty" yaml:"remote_dir,omitempty"` 25 Error string `json:"error,omitempty" yaml:"error,omitempty"` 26 PodIP string `json:"pod_ip,omitempty" yaml:"pod_ip,omitempty"` 27 Port int32 `json:"port,omitempty" yaml:"port,omitempty"` 28 Mounts []string `json:"mounts,omitempty" yaml:"mounts,omitempty"` 29 } 30 31 type Info struct { 32 ID string `json:"id,omitempty" yaml:"id,omitempty"` 33 Name string `json:"name,omitempty" yaml:"name,omitempty"` 34 Disposition string `json:"disposition,omitempty" yaml:"disposition,omitempty"` 35 Message string `json:"message,omitempty" yaml:"message,omitempty"` 36 WorkloadKind string `json:"workload_kind,omitempty" yaml:"workload_kind,omitempty"` 37 TargetHost string `json:"target_host,omitempty" yaml:"target_host,omitempty"` 38 TargetPort int32 `json:"target_port,omitempty" yaml:"target_port,omitempty"` 39 ServicePortID string `json:"service_port_id,omitempty" yaml:"service_port_id,omitempty"` 40 Environment map[string]string `json:"environment,omitempty" yaml:"environment,omitempty"` 41 Mount *Mount `json:"mount,omitempty" yaml:"mount,omitempty"` 42 FilterDesc string `json:"filter_desc,omitempty" yaml:"filter_desc,omitempty"` 43 Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"` 44 HttpFilter []string `json:"http_filter,omitempty" yaml:"http_filter,omitempty"` 45 Global bool `json:"global,omitempty" yaml:"global,omitempty"` 46 PreviewURL string `json:"preview_url,omitempty" yaml:"preview_url,omitempty"` 47 Ingress *Ingress `json:"ingress,omitempty" yaml:"ingress,omitempty"` 48 debug bool 49 } 50 51 func NewIngress(ps *manager.PreviewSpec) *Ingress { 52 if ps == nil { 53 return nil 54 } 55 ii := ps.Ingress 56 if ii == nil { 57 return nil 58 } 59 return &Ingress{ 60 Host: ii.Host, 61 Port: ii.Port, 62 UseTLS: ii.UseTls, 63 L5Host: ii.L5Host, 64 } 65 } 66 67 func PreviewURL(pu string) string { 68 if !(pu == "" || strings.HasPrefix(pu, "https://") || strings.HasPrefix(pu, "http://")) { 69 pu = "https://" + pu 70 } 71 return pu 72 } 73 74 func NewMount(ctx context.Context, ii *manager.InterceptInfo, mountError string) *Mount { 75 if mountError != "" { 76 return &Mount{Error: mountError} 77 } 78 if ii.MountPoint != "" { 79 var port int32 80 if client.GetConfig(ctx).Intercept().UseFtp { 81 port = ii.FtpPort 82 } else { 83 port = ii.SftpPort 84 } 85 var mounts []string 86 if tpMounts := ii.Environment["TELEPRESENCE_MOUNTS"]; tpMounts != "" { 87 // This is a Unix path, so we cannot use filepath.SplitList 88 mounts = strings.Split(tpMounts, ":") 89 } 90 return &Mount{ 91 LocalDir: ii.ClientMountPoint, 92 RemoteDir: ii.MountPoint, 93 PodIP: ii.PodIp, 94 Port: port, 95 Mounts: mounts, 96 } 97 } 98 return nil 99 } 100 101 func NewInfo(ctx context.Context, ii *manager.InterceptInfo, mountError string) *Info { 102 spec := ii.Spec 103 return &Info{ 104 ID: ii.Id, 105 Name: spec.Name, 106 Disposition: ii.Disposition.String(), 107 Message: ii.Message, 108 WorkloadKind: spec.WorkloadKind, 109 TargetHost: spec.TargetHost, 110 TargetPort: spec.TargetPort, 111 Mount: NewMount(ctx, ii, mountError), 112 ServicePortID: spec.ServicePortIdentifier, 113 Environment: ii.Environment, 114 FilterDesc: ii.MechanismArgsDesc, 115 Metadata: ii.Metadata, 116 HttpFilter: spec.MechanismArgs, 117 Global: spec.Mechanism == "tcp", 118 PreviewURL: PreviewURL(ii.PreviewDomain), 119 Ingress: NewIngress(ii.PreviewSpec), 120 } 121 } 122 123 func (ii *Info) WriteTo(w io.Writer) (int64, error) { 124 kvf := ioutil.DefaultKeyValueFormatter() 125 kvf.Prefix = " " 126 kvf.Add("Intercept name", ii.Name) 127 kvf.Add("State", func() string { 128 msg := "" 129 if manager.InterceptDispositionType_value[ii.Disposition] > int32(manager.InterceptDispositionType_WAITING) { 130 msg += "error: " 131 } 132 msg += ii.Disposition 133 if ii.Message != "" { 134 msg += ": " + ii.Message 135 } 136 return msg 137 }()) 138 kvf.Add("Workload kind", ii.WorkloadKind) 139 140 if ii.debug { 141 kvf.Add("ID", ii.ID) 142 } 143 144 kvf.Add( 145 "Destination", 146 net.JoinHostPort(ii.TargetHost, fmt.Sprintf("%d", ii.TargetPort)), 147 ) 148 149 if ii.ServicePortID != "" { 150 kvf.Add("Service Port Identifier", ii.ServicePortID) 151 } 152 if ii.debug { 153 m := "http" 154 if ii.Global { 155 m = "tcp" 156 } 157 kvf.Add("Mechanism", m) 158 kvf.Add("Mechanism Command", fmt.Sprintf("%q", ii.FilterDesc)) 159 kvf.Add("Metadata", fmt.Sprintf("%q", ii.Metadata)) 160 } 161 162 if m := ii.Mount; m != nil { 163 if m.LocalDir != "" { 164 kvf.Add("Volume Mount Point", m.LocalDir) 165 } else if m.Error != "" { 166 kvf.Add("Volume Mount Error", m.Error) 167 } 168 } 169 170 kvf.Add("Intercepting", func() string { 171 if ii.FilterDesc != "" { 172 return ii.FilterDesc 173 } 174 if ii.Global { 175 return `using mechanism "tcp"` 176 } 177 return fmt.Sprintf("using mechanism=%q with args=%q", "http", ii.HttpFilter) 178 }()) 179 180 if ii.PreviewURL != "" { 181 previewURL := ii.PreviewURL 182 // Right now SystemA gives back domains with the leading "https://", but 183 // let's not rely on that. 184 if !strings.HasPrefix(previewURL, "https://") && !strings.HasPrefix(previewURL, "http://") { 185 previewURL = "https://" + previewURL 186 } 187 kvf.Add("Preview URL", previewURL) 188 } 189 if in := ii.Ingress; in != nil { 190 kvf.Add("Layer 5 Hostname", in.L5Host) 191 } 192 return kvf.WriteTo(w) 193 }