Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,13 @@ start-docs-website:

generate-ca-certificates:
scripts/generate-ca-certificates.sh cli/internal/client/ca-certificates.pem


start-proxy: install-cli
tyger-proxy start -f <($(MAKE) get-proxy-config)

run-proxy: install-cli
tyger-proxy run -f <($(MAKE) get-proxy-config)

kill-proxy:
killall -s SIGINT tyger-proxy
6 changes: 0 additions & 6 deletions Makefile.cloud
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,6 @@ get-proxy-config:
$${auth_parameters}
"

start-proxy: install-cli
tyger-proxy start -f <($(MAKE) get-proxy-config)

kill-proxy:
killall tyger-proxy

connect-db: set-context
helm_values=$$(helm get values -n ${HELM_NAMESPACE} ${HELM_RELEASE} -o json || true)

Expand Down
79 changes: 53 additions & 26 deletions cli/cmd/tyger-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"net/url"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -133,45 +134,71 @@ func readProxyOptions(optionsFilePath string, options *tygerproxy.ProxyOptions)
return errors.New("serverUrl must be specified")
}

if options.ManagedIdentity {
if options.ServicePrincipal != "" {
return errors.New("servicePrincipal cannot be specified when using managed identity")
parsedUrl, err := url.Parse(options.ServerUrl)
if err != nil {
return fmt.Errorf("invalid serverUrl: %v", err)
}

if parsedUrl.Scheme == "ssh" || parsedUrl.Scheme == "http+unix" {
if options.ManagedIdentity {
return errors.New("managedIdentity cannot be specified when using SSH or Unix socket connection")
}
if options.CertificatePath != "" {
return errors.New("certificatePath cannot be specified when using managed identity")
if options.GitHub {
return errors.New("github cannot be specified when using SSH or Unix socket connection")
}
if options.CertificateThumbprint != "" {
return errors.New("certificateThumbprint cannot be specified when using managed identity")
}
} else if options.GitHub {
if options.ServicePrincipal != "" {
return errors.New("servicePrincipal cannot be specified when using GitHub authentication")
return errors.New("servicePrincipal cannot be specified when using SSH or Unix socket connection")
}
if options.CertificatePath != "" {
return errors.New("certificatePath cannot be specified when using GitHub authentication")
return errors.New("certificatePath cannot be specified when using SSH or Unix socket connection")
}
if options.CertificateThumbprint != "" {
return errors.New("certificateThumbprint cannot be specified when using GitHub authentication")
return errors.New("certificateThumbprint cannot be specified when using SSH or Unix socket connection")
}
} else {
if options.ServicePrincipal == "" {
return errors.New("if both managedIdentity and github are both not true, servicePrincipal must be specified in the options file")
if options.TargetFederatedIdentity != "" {
return errors.New("targetFederatedIdentity cannot be specified when using SSH or Unix socket connection")
}

if runtime.GOOS == "windows" {
if options.CertificatePath == "" && options.CertificateThumbprint == "" {
return errors.New("either certificatePath or certificateThumbprint must be specified in the options file")
} else {
if options.ManagedIdentity {
if options.ServicePrincipal != "" {
return errors.New("servicePrincipal cannot be specified when using managed identity")
}
if options.CertificatePath != "" {
return errors.New("certificatePath cannot be specified when using managed identity")
}
if options.CertificateThumbprint != "" {
return errors.New("certificateThumbprint cannot be specified when using managed identity")
}
} else if options.GitHub {
if options.ServicePrincipal != "" {
return errors.New("servicePrincipal cannot be specified when using GitHub authentication")
}
if options.CertificatePath != "" {
return errors.New("certificatePath cannot be specified when using GitHub authentication")
}
if options.CertificateThumbprint != "" {
return errors.New("certificateThumbprint cannot be specified when using GitHub authentication")
}
} else {
if options.ServicePrincipal == "" {
return errors.New("if both managedIdentity and github are both not true, servicePrincipal must be specified in the options file")
}

if runtime.GOOS == "windows" {
if options.CertificatePath == "" && options.CertificateThumbprint == "" {
return errors.New("either certificatePath or certificateThumbprint must be specified in the options file")
}

if options.CertificatePath != "" && options.CertificateThumbprint != "" {
return errors.New("certificatePath and certificateThumbprint cannot both be specified")
if options.CertificatePath != "" && options.CertificateThumbprint != "" {
return errors.New("certificatePath and certificateThumbprint cannot both be specified")
}
} else if options.CertificatePath == "" {
return errors.New("certificatePath must be specified in the options file")
}
} else if options.CertificatePath == "" {
return errors.New("certificatePath must be specified in the options file")
}

if options.TargetFederatedIdentity != "" {
return errors.New("targetFederatedIdentity cannot be specified when using service principal authentication")
if options.TargetFederatedIdentity != "" {
return errors.New("targetFederatedIdentity cannot be specified when using service principal authentication")
}
}
}

Expand Down
31 changes: 27 additions & 4 deletions cli/cmd/tyger-proxy/proxyrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
package main

import (
"context"
"io"
"os"
"os/signal"
"path"
"path/filepath"
"syscall"

"github.com/microsoft/tyger/cli/internal/controlplane"
"github.com/microsoft/tyger/cli/internal/logging"
Expand Down Expand Up @@ -66,12 +69,19 @@ func newProxyRunCommand(optionsFilePath *string, options *tygerproxy.ProxyOption
log.Info().Str("path", logFile.Name()).Msg("Logging to file")
}

client, err := controlplane.Login(cmd.Context(), options.LoginConfig)
// Set up signal handling for graceful shutdown
ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

client, serviceMetadata, err := controlplane.Login(ctx, options.LoginConfig)
if err != nil {
log.Fatal().Err(err).Msg("login failed")
}

_, err = tygerproxy.RunProxy(cmd.Context(), client, options, log.Logger)
closeProxy, err := tygerproxy.RunProxy(ctx, client, options, serviceMetadata, log.Logger)
if err != nil {
if err == tygerproxy.ErrProxyAlreadyRunning {
log.Info().Int("port", options.Port).Msg("A proxy is already running at this address.")
Expand All @@ -83,8 +93,21 @@ func newProxyRunCommand(optionsFilePath *string, options *tygerproxy.ProxyOption

log.Info().Int("port", options.Port).Msg(proxyIsListeningMessage)

// wait indefinitely
<-(make(chan any))
// Wait for shutdown signal
sig := <-sigChan
log.Info().Str("signal", sig.String()).Msg("Received shutdown signal, cleaning up...")

// Cancel context to trigger cleanup of SSH tunnels and other resources
cancel()

// Close the proxy
if closeProxy != nil {
if err := closeProxy(); err != nil {
log.Warn().Err(err).Msg("Error closing proxy")
}
}

log.Info().Msg("Proxy shutdown complete")
},
}

Expand Down
6 changes: 6 additions & 0 deletions cli/integrationtest/expected_openapi_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,12 @@ components:
items:
type: string
nullable: true
storageEndpoints:
type: array
items:
type: string
format: uri
nullable: true
additionalProperties: false
Socket:
type: object
Expand Down
Loading
Loading