Skip to content

Commit

Permalink
feat: add a url field to port that autopopulates if application proto…
Browse files Browse the repository at this point in the history
  • Loading branch information
h4ck3rk3y committed Feb 26, 2024
1 parent 3a1b56c commit 35c913b
Show file tree
Hide file tree
Showing 35 changed files with 265 additions and 117 deletions.
3 changes: 2 additions & 1 deletion cli/cli/kurtosis_gateway/connection/connection.go
Expand Up @@ -21,6 +21,7 @@ const (
portForwardTimeoutDuration = 5 * time.Second
grpcPortId = "grpc"
emptyApplicationProtocol = ""
emptyPortUrl = ""
portForwardTimeBetweenRetries = 5 * time.Second
)

Expand Down Expand Up @@ -175,7 +176,7 @@ func newLocalPortToPodPortConnection(kubernetesRestConfig *k8s_rest.Config, podP
return nil, stacktrace.NewError("Expected to be able to find port_spec id of remote port '%v', instead found nothing", remotePort)
}
// Port forwarding in kubernetes only supports TCP
localPortSpec, err := port_spec.NewPortSpec(localPort, port_spec.TransportProtocol_TCP, emptyApplicationProtocol, noWait)
localPortSpec, err := port_spec.NewPortSpec(localPort, port_spec.TransportProtocol_TCP, emptyApplicationProtocol, noWait, emptyPortUrl)
if err != nil {
return nil, stacktrace.Propagate(err, "Expected to be able to create port-spec describing local port '%v', instead a non-nil err was returned", localPort)
}
Expand Down
5 changes: 3 additions & 2 deletions cli/cli/kurtosis_gateway/connection/provider.go
Expand Up @@ -24,6 +24,7 @@ const (
httpApplicationProtocol = "http"
// this doesn't have any effect as this is just the gateway
emptyStorageClassName = ""
emptyUrl = ""
)

var noWait *port_spec.Wait = nil
Expand Down Expand Up @@ -56,7 +57,7 @@ func NewGatewayConnectionProvider(ctx context.Context, kubernetesConfig *restcli

func (provider *GatewayConnectionProvider) ForEngine(engine *engine.Engine) (GatewayConnectionToKurtosis, error) {
// Forward public GRPC ports of engine
enginePublicGrpcPortSpec, err := port_spec.NewPortSpec(kurtosis_context.DefaultGrpcEngineServerPortNum, port_spec.TransportProtocol_TCP, httpApplicationProtocol, noWait)
enginePublicGrpcPortSpec, err := port_spec.NewPortSpec(kurtosis_context.DefaultGrpcEngineServerPortNum, port_spec.TransportProtocol_TCP, httpApplicationProtocol, noWait, emptyUrl)
if err != nil {
return nil, stacktrace.Propagate(err, "Expected to be able to get a port-spec describing the public GRPC port of a Kurtosis engine, instead a non-nil error was returned")
}
Expand All @@ -78,7 +79,7 @@ func (provider *GatewayConnectionProvider) ForEnclaveApiContainer(enclaveInfo *k
apiContainerInfo := enclaveInfo.ApiContainerInfo
// We want the port on the kubernetes pod that tbe api container is listening on
grpcPortUint16 := uint16(apiContainerInfo.GetGrpcPortInsideEnclave())
apiContainerGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortUint16, port_spec.TransportProtocol_TCP, httpApplicationProtocol, noWait)
apiContainerGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortUint16, port_spec.TransportProtocol_TCP, httpApplicationProtocol, noWait, emptyUrl)
if err != nil {
return nil, stacktrace.Propagate(err, "Expected to be able to get a port spec describing api container GRPC port on port number'%v', instead a non-nil error was returned", grpcPortUint16)
}
Expand Down
3 changes: 2 additions & 1 deletion cli/cli/kurtosis_gateway/port_utils/free_port.go
Expand Up @@ -10,6 +10,7 @@ import (
const (
tcpProtocolStr = "tcp"
emptyApplicationProtocol = ""
emptyUrl = ""
)

var noWait *port_spec.Wait = nil
Expand All @@ -31,7 +32,7 @@ func GetFreeTcpPort(networkInterface string) (resultFreePortSpec *port_spec.Port
portNumber := localHostPortListener.Addr().(*net.TCPAddr).Port
portNumberUint16 := uint16(portNumber)

localHostPortSpec, err := port_spec.NewPortSpec(portNumberUint16, port_spec.TransportProtocol_TCP, emptyApplicationProtocol, noWait)
localHostPortSpec, err := port_spec.NewPortSpec(portNumberUint16, port_spec.TransportProtocol_TCP, emptyApplicationProtocol, noWait, emptyUrl)
if err != nil {
return nil, stacktrace.Propagate(err, "Expected to be able to create a port spec describing a free open port on localhost, instead a non-nil error was returned")
}
Expand Down
Expand Up @@ -291,7 +291,7 @@ func (service *ApiContainerGatewayServiceServer) startRunningConnectionForKurtos
continue
}
portNumberUint16 := uint16(coreApiPort.GetNumber())
remotePortSpec, err := port_spec.NewPortSpec(portNumberUint16, port_spec.TransportProtocol_TCP, coreApiPort.GetMaybeApplicationProtocol(), nil)
remotePortSpec, err := port_spec.NewPortSpec(portNumberUint16, port_spec.TransportProtocol_TCP, coreApiPort.GetMaybeApplicationProtocol(), nil, "")
if err != nil {
return nil, stacktrace.Propagate(err, "Expected to be able to create port spec describing remote port '%v', instead a non-nil error was returned", portSpecId)
}
Expand Down
Expand Up @@ -33,6 +33,8 @@ const (
HttpApplicationProtocol = "http"

GitHubAuthStorageDirPath = "/kurtosis-data/github-auth/"

EmptyApplicationURL = ""
)

// This maps a Docker container's status to a binary "is the container considered running?" determiner
Expand Down
Expand Up @@ -129,7 +129,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer(
return nil, stacktrace.Propagate(err, "An error occurred creating a new wait with default values")
}

privateGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortNum, apiContainerTransportProtocol, consts.HttpApplicationProtocol, defaultWait)
privateGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortNum, apiContainerTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down Expand Up @@ -163,12 +163,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer(
}

if shouldStartInDebugMode {
debugServerPortSpec, err := port_spec.NewPortSpec(
uint16(apicDebugServerPort),
apiContainerTransportProtocol,
consts.HttpApplicationProtocol,
defaultWait,
)
debugServerPortSpec, err := port_spec.NewPortSpec(uint16(apicDebugServerPort), apiContainerTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -64,7 +64,7 @@ func CreateEngine(
return nil, stacktrace.Propagate(err, "An error occurred creating a wait with default values")
}

privateGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortNum, consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait)
privateGrpcPortSpec, err := port_spec.NewPortSpec(grpcPortNum, consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down Expand Up @@ -137,7 +137,7 @@ func CreateEngine(
}
logrus.Infof("Reverse proxy started.")

enclaveManagerUIPortSpec, err := port_spec.NewPortSpec(uint16(enclaveManagerUIPort), consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait)
enclaveManagerUIPortSpec, err := port_spec.NewPortSpec(uint16(enclaveManagerUIPort), consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand All @@ -147,12 +147,7 @@ func CreateEngine(
)
}

enclaveManagerApiPortSpec, err := port_spec.NewPortSpec(
uint16(enclaveManagerAPIPort),
consts.EngineTransportProtocol,
consts.HttpApplicationProtocol,
defaultWait,
)
enclaveManagerApiPortSpec, err := port_spec.NewPortSpec(uint16(enclaveManagerAPIPort), consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand All @@ -162,7 +157,7 @@ func CreateEngine(
)
}

restAPIPortSpec, err := port_spec.NewPortSpec(engine.RESTAPIPortAddr, consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait)
restAPIPortSpec, err := port_spec.NewPortSpec(engine.RESTAPIPortAddr, consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down Expand Up @@ -217,12 +212,7 @@ func CreateEngine(

// Configure the debug port only if it's required
if shouldStartInDebugMode {
debugServerPortSpec, err := port_spec.NewPortSpec(
uint16(engineDebugServerPort),
consts.EngineTransportProtocol,
consts.HttpApplicationProtocol,
defaultWait,
)
debugServerPortSpec, err := port_spec.NewPortSpec(uint16(engineDebugServerPort), consts.EngineTransportProtocol, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -210,7 +210,7 @@ func deserialize_pre_2022_03_02_PortSpecs(specsStr string) (map[string]*port_spe
//TODO we are passing nil wait so far because the wait's serialization/deserialization logic is not added yet because
//TODO the port wait feature is in the design stage and its name and fields could change,
//TODO we will include this in a next PR
portSpec, err := port_spec.NewPortSpec(portNumUint16, portProtocol, emptyApplicationProtocol, nil)
portSpec, err := port_spec.NewPortSpec(portNumUint16, portProtocol, emptyApplicationProtocol, nil, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -8,6 +8,7 @@ import (

const (
httpProtocolStr = "http"
emptyUrl = "emptyUrl"
)

type fluentbitContainerConfigProvider struct {
Expand All @@ -21,7 +22,7 @@ func newFluentbitContainerConfigProvider(config *FluentbitConfig, tcpPortNumber
}

func (fluent *fluentbitContainerConfigProvider) GetPrivateTcpPortSpec() (*port_spec.PortSpec, error) {
privateTcpPortSpec, err := port_spec.NewPortSpec(fluent.tcpPortNumber, tcpTransportProtocol, httpProtocolStr, nil)
privateTcpPortSpec, err := port_spec.NewPortSpec(fluent.tcpPortNumber, tcpTransportProtocol, httpProtocolStr, nil, emptyUrl)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand All @@ -34,7 +35,7 @@ func (fluent *fluentbitContainerConfigProvider) GetPrivateTcpPortSpec() (*port_s
}

func (fluent *fluentbitContainerConfigProvider) GetPrivateHttpPortSpec() (*port_spec.PortSpec, error) {
privateHttpPortSpec, err := port_spec.NewPortSpec(fluent.httpPortNumber, httpTransportProtocol, httpProtocolStr, nil)
privateHttpPortSpec, err := port_spec.NewPortSpec(fluent.httpPortNumber, httpTransportProtocol, httpProtocolStr, nil, emptyUrl)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -71,7 +71,7 @@ func (traefik *traefikContainerConfigProvider) GetContainerArgs(
}

// Publish HTTP and Dashboard entrypoint ports
privateHttpPortSpec, err := port_spec.NewPortSpec(httpPort, port_spec.TransportProtocol_TCP, consts.HttpApplicationProtocol, defaultWait)
privateHttpPortSpec, err := port_spec.NewPortSpec(httpPort, port_spec.TransportProtocol_TCP, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand All @@ -84,7 +84,7 @@ func (traefik *traefikContainerConfigProvider) GetContainerArgs(
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred transforming the private http port spec to a Docker port")
}
privateDashboardPortSpec, err := port_spec.NewPortSpec(dashboardPort, port_spec.TransportProtocol_TCP, consts.HttpApplicationProtocol, defaultWait)
privateDashboardPortSpec, err := port_spec.NewPortSpec(dashboardPort, port_spec.TransportProtocol_TCP, consts.HttpApplicationProtocol, defaultWait, consts.EmptyApplicationURL)
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -48,6 +48,8 @@ const (
containerLogsFilename = "output.log"
createdDirPerms = 0755
numContainersToDumpAtOnce = 20

emptyUrl = ""
)

// !!!WARNING!!!
Expand Down Expand Up @@ -185,7 +187,7 @@ func GetPublicPortBindingFromPrivatePortSpec(privatePortSpec *port_spec.PortSpec
if privatePortSpec.GetMaybeApplicationProtocol() != nil {
maybeApplicationProtocol = *privatePortSpec.GetMaybeApplicationProtocol()
}
publicPortSpec, err := port_spec.NewPortSpec(hostMachinePortNumUint16, privatePortSpec.GetTransportProtocol(), maybeApplicationProtocol, privatePortSpec.GetWait())
publicPortSpec, err := port_spec.NewPortSpec(hostMachinePortNumUint16, privatePortSpec.GetTransportProtocol(), maybeApplicationProtocol, privatePortSpec.GetWait(), emptyUrl)
if err != nil {
return nil, nil, stacktrace.Propagate(
err, "An error occurred creating public port spec with host machine port num '%v', transport protocol '%v' and application protocol '%v'", hostMachinePortNumUint16, privatePortSpec.GetTransportProtocol().String(), maybeApplicationProtocol)
Expand Down
Expand Up @@ -77,6 +77,7 @@ func SerializePortSpecs(ports map[string]*port_spec.PortSpec) (*docker_label_val

//TODO we are not serializing the port wait so far, because this in design stage and the name
//TODO and even the fields could change, so we don't want to brake anything until we add the port wait configs to users
//TODO we aren't serializing URL for now
if previousPortId, found := usedPortSpecStrs[portSpecStr]; found {
return nil, stacktrace.NewError(
"Port '%v' declares spec string '%v', but that spec string is already in use for port '%v'",
Expand Down Expand Up @@ -212,7 +213,7 @@ func deserializePortSpecStrUsingDelimiters(
//TODO we are passing nil wait so far because the wait's serialization/deserialization logic is not added yet because
//TODO the port wait feature is in the design stage and its name and fields could change,
//TODO we will include this in a next PR
portSpec, err := port_spec.NewPortSpec(portNumUint16, portProtocol, portApplicationProtocolStr, nil)
portSpec, err := port_spec.NewPortSpec(portNumUint16, portProtocol, portApplicationProtocolStr, nil, "")
if err != nil {
return nil, stacktrace.Propagate(
err,
Expand Down
Expand Up @@ -15,13 +15,13 @@ func TestValidSerDe(t *testing.T) {
port1Id := "port1"
port1Num := uint16(23)
port1Protocol := port_spec.TransportProtocol_TCP
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest)
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 1 spec")

port2Id := "port2"
port2Num := uint16(45)
port2Protocol := port_spec.TransportProtocol_TCP
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest)
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 2 spec")

input := map[string]*port_spec.PortSpec{
Expand Down Expand Up @@ -68,7 +68,7 @@ func TestDisallowedCharsSerialization(t *testing.T) {
portId := "ohyeah" + disallowedChar
portNum := uint16(45)
portProtocol := port_spec.TransportProtocol_TCP
portSpec, err := port_spec.NewPortSpec(portNum, portProtocol, "", portWaitForTest)
portSpec, err := port_spec.NewPortSpec(portNum, portProtocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port spec for port with ID '%v'", portId)

ports := map[string]*port_spec.PortSpec{
Expand All @@ -86,13 +86,13 @@ func TestDuplicatedPortNumDifferentProtoSerialization(t *testing.T) {
port1Id := "port1"
port1Num := dupedPortNum
port1Protocol := port_spec.TransportProtocol_TCP
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest)
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 1 spec")

port2Id := "port2"
port2Num := dupedPortNum
port2Protocol := port_spec.TransportProtocol_UDP
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest)
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 2 spec")

input := map[string]*port_spec.PortSpec{
Expand All @@ -110,13 +110,13 @@ func TestDuplicatedPortNumSameProtoSerialization(t *testing.T) {
port1Id := "port1"
port1Num := dupedPortNum
port1Protocol := port_spec.TransportProtocol_TCP
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest)
port1Spec, err := port_spec.NewPortSpec(port1Num, port1Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 1 spec")

port2Id := "port2"
port2Num := dupedPortNum
port2Protocol := port_spec.TransportProtocol_TCP
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest)
port2Spec, err := port_spec.NewPortSpec(port2Num, port2Protocol, "", portWaitForTest, "")
require.NoError(t, err, "An unexpected error occurred creating port 2 spec")

input := map[string]*port_spec.PortSpec{
Expand Down Expand Up @@ -190,34 +190,34 @@ func TestNoPortProtosHaveDisallowedChars(t *testing.T) {
}

func TestValidatePortSpec_ValidApplicationProtocol(t *testing.T) {
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_UDP, "H-ttp.2", portWaitForTest)
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_UDP, "H-ttp.2", portWaitForTest, "")
err := validatePortSpec("PortId", spec)
require.Nil(t, err, "Error cannot be nil")
}

func TestValidatePortSpec_InvalidPortId(t *testing.T) {
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_TCP, "https", portWaitForTest)
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_TCP, "https", portWaitForTest, "")
err := validatePortSpec(",portid/", spec)
require.NotNil(t, err, "Error cannot be nil")
require.ErrorContains(t, err, fmt.Sprintf("Port ID '%v' contains disallowed char '%v'", ",portid/", portSpecsSeparator))
}

func TestValidatePortSpec_InvalidApplicationProtocol(t *testing.T) {
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_TCP, "/https,", portWaitForTest)
spec, _ := port_spec.NewPortSpec(100, port_spec.TransportProtocol_TCP, "/https,", portWaitForTest, "")
err := validatePortSpec("PortId", spec)
require.NotNil(t, err, "Error cannot be nil")
require.ErrorContains(t, err, fmt.Sprintf("Application Protocol '%v' associated with port ID '%v' contains disallowed char '%v'", "/https,", "PortId", portNumAndProtocolSeparator))

spec, _ = port_spec.NewPortSpec(100, port_spec.TransportProtocol_UDP, " H-ttp.2", portWaitForTest)
spec, _ = port_spec.NewPortSpec(100, port_spec.TransportProtocol_UDP, " H-ttp.2", portWaitForTest, "")
err = validatePortSpec("PortId", spec)
require.NotNil(t, err, "Error cannot be nil")
require.ErrorContains(t, err, "application protocol ' H-ttp.2' associated with port ID 'PortId' contains invalid character(s). It must only contain [a-zA-Z0-9+.-]")
}

func TestSerializeMethod_ValidPortSpecs(t *testing.T) {
specs := map[string]*port_spec.PortSpec{}
portOne, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_TCP, "", portWaitForTest)
portTwo, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_UDP, "https", portWaitForTest)
portOne, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_TCP, "", portWaitForTest, "")
portTwo, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_UDP, "https", portWaitForTest, "")

specs["portOne"] = portOne
specs["portTwo"] = portTwo
Expand All @@ -236,8 +236,8 @@ func TestDeSerializeMethod_ValidPortSpecs(t *testing.T) {
expectedSpecs := map[string]*port_spec.PortSpec{}

//TODO use portWaitForTest when we include the wait serialization/deserialization
expectedPortOne, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_TCP, "", nil)
expectedPortTwo, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_UDP, "https", nil)
expectedPortOne, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_TCP, "", nil, "")
expectedPortTwo, _ := port_spec.NewPortSpec(3333, port_spec.TransportProtocol_UDP, "https", nil, "")
expectedSpecs["portOne"] = expectedPortOne
expectedSpecs["portTwo"] = expectedPortTwo

Expand Down

0 comments on commit 35c913b

Please sign in to comment.