istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/test/framework/components/echo/port.go (about) 1 // Copyright Istio Authors 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 echo 16 17 import ( 18 "fmt" 19 "reflect" 20 21 "istio.io/istio/pkg/config/protocol" 22 "istio.io/istio/pkg/test/echo/common/scheme" 23 ) 24 25 // NoServicePort defines the ServicePort value for a Port that is a workload-only port. 26 const NoServicePort = -1 27 28 // Port exposed by an Echo Instance 29 type Port struct { 30 // Name of this port 31 Name string 32 33 // Protocol to be used for the port. 34 Protocol protocol.Instance 35 36 // ServicePort number where the service can be reached. Does not necessarily 37 // map to the corresponding port numbers for the instances behind the 38 // service. If zero (default), a service port will be automatically generated for this port. 39 // If set to NoServicePort, this port will be assumed to be a workload-only port. 40 ServicePort int 41 42 // WorkloadPort number where the workload is listening for connections. 43 // This need not be the same as the ServicePort where the service is accessed. 44 WorkloadPort int 45 46 // TLS determines whether the connection will be plain text or TLS. By default this is false (plain text). 47 TLS bool 48 49 // ServerFirst determines whether the port will use server first communication, meaning the client will not send the first byte. 50 ServerFirst bool 51 52 // InstanceIP determines if echo will listen on the instance IP; otherwise, it will listen on wildcard 53 InstanceIP bool 54 55 // LocalhostIP determines if echo will listen on the localhost IP; otherwise, it will listen on wildcard 56 LocalhostIP bool 57 } 58 59 // IsWorkloadOnly returns true if there is no service port specified for this Port. 60 func (p Port) IsWorkloadOnly() bool { 61 return p.ServicePort == NoServicePort 62 } 63 64 // Scheme infers the scheme to be used based on the Protocol. 65 func (p Port) Scheme() (scheme.Instance, error) { 66 switch p.Protocol { 67 case protocol.GRPC, protocol.GRPCWeb, protocol.HTTP2: 68 return scheme.GRPC, nil 69 case protocol.HTTP: 70 return scheme.HTTP, nil 71 case protocol.HTTPS: 72 return scheme.HTTPS, nil 73 case protocol.TCP: 74 return scheme.TCP, nil 75 default: 76 return "", fmt.Errorf("failed creating call for port %s: unsupported protocol %s", 77 p.Name, p.Protocol) 78 } 79 } 80 81 type Ports []Port 82 83 func (ps Ports) Contains(p Port) bool { 84 for _, port := range ps { 85 if reflect.DeepEqual(port, p) { 86 return true 87 } 88 } 89 return false 90 } 91 92 // ForName returns the first port found with the given name. 93 func (ps Ports) ForName(name string) (Port, bool) { 94 for _, port := range ps { 95 if name == port.Name { 96 return port, true 97 } 98 } 99 return Port{}, false 100 } 101 102 // MustForName calls ForName and panics if not found. 103 func (ps Ports) MustForName(name string) Port { 104 p, found := ps.ForName(name) 105 if !found { 106 panic("port does not exist for name " + name) 107 } 108 return p 109 } 110 111 // ForProtocol returns the first port found with the given protocol. 112 func (ps Ports) ForProtocol(protocol protocol.Instance) (Port, bool) { 113 for _, p := range ps { 114 if p.Protocol == protocol { 115 return p, true 116 } 117 } 118 return Port{}, false 119 } 120 121 // ForServicePort returns the first port found with the given service port. 122 func (ps Ports) ForServicePort(port int) (Port, bool) { 123 for _, p := range ps { 124 if p.ServicePort == port { 125 return p, true 126 } 127 } 128 return Port{}, false 129 } 130 131 // MustForProtocol calls ForProtocol and panics if not found. 132 func (ps Ports) MustForProtocol(protocol protocol.Instance) Port { 133 p, found := ps.ForProtocol(protocol) 134 if !found { 135 panic("port does not exist for protocol " + protocol) 136 } 137 return p 138 } 139 140 // GetServicePorts returns the subset of ports that contain a service port. 141 func (ps Ports) GetServicePorts() Ports { 142 out := make(Ports, 0, len(ps)) 143 for _, p := range ps { 144 if !p.IsWorkloadOnly() { 145 out = append(out, p) 146 } 147 } 148 return out 149 } 150 151 // GetWorkloadOnlyPorts returns the subset of ports that do not contain a service port. 152 func (ps Ports) GetWorkloadOnlyPorts() Ports { 153 out := make(Ports, 0, len(ps)) 154 for _, p := range ps { 155 if p.IsWorkloadOnly() { 156 out = append(out, p) 157 } 158 } 159 return out 160 }