Merge branch 'cloudflare:master' into master
This commit is contained in:
commit
24ee7c0ddc
|
@ -22,7 +22,7 @@ RUN .teamcity/install-cloudflare-go.sh
|
||||||
RUN PATH="/tmp/go/bin:$PATH" make cloudflared
|
RUN PATH="/tmp/go/bin:$PATH" make cloudflared
|
||||||
|
|
||||||
# use a distroless base image with glibc
|
# use a distroless base image with glibc
|
||||||
FROM gcr.io/distroless/base-debian11:nonroot
|
FROM gcr.io/distroless/base-debian12:nonroot
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ RUN .teamcity/install-cloudflare-go.sh
|
||||||
RUN GOOS=linux GOARCH=amd64 PATH="/tmp/go/bin:$PATH" make cloudflared
|
RUN GOOS=linux GOARCH=amd64 PATH="/tmp/go/bin:$PATH" make cloudflared
|
||||||
|
|
||||||
# use a distroless base image with glibc
|
# use a distroless base image with glibc
|
||||||
FROM gcr.io/distroless/base-debian11:nonroot
|
FROM gcr.io/distroless/base-debian12:nonroot
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ RUN .teamcity/install-cloudflare-go.sh
|
||||||
RUN GOOS=linux GOARCH=arm64 PATH="/tmp/go/bin:$PATH" make cloudflared
|
RUN GOOS=linux GOARCH=arm64 PATH="/tmp/go/bin:$PATH" make cloudflared
|
||||||
|
|
||||||
# use a distroless base image with glibc
|
# use a distroless base image with glibc
|
||||||
FROM gcr.io/distroless/base-debian11:nonroot-arm64
|
FROM gcr.io/distroless/base-debian12:nonroot-arm64
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
LABEL org.opencontainers.image.source="https://github.com/cloudflare/cloudflared"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2025.2.1
|
||||||
|
- 2025-02-26 TUN-9016: update base-debian to v12
|
||||||
|
- 2025-02-25 TUN-8960: Connect to FED API GW based on the OriginCert's endpoint
|
||||||
|
- 2025-02-25 TUN-9007: modify logic to resolve region when the tunnel token has an endpoint field
|
||||||
|
- 2025-02-13 SDLC-3762: Remove backstage.io/source-location from catalog-info.yaml
|
||||||
|
- 2025-02-06 TUN-8914: Create a flags module to group all cloudflared cli flags
|
||||||
|
|
||||||
2025.2.0
|
2025.2.0
|
||||||
- 2025-02-03 TUN-8914: Add a new configuration to locally override the max-active-flows
|
- 2025-02-03 TUN-8914: Add a new configuration to locally override the max-active-flows
|
||||||
- 2025-02-03 Bump x/crypto to 0.31.0
|
- 2025-02-03 Bump x/crypto to 0.31.0
|
||||||
|
|
|
@ -149,4 +149,7 @@ const (
|
||||||
|
|
||||||
// MetricsUpdateFreq is the command line flag to define how frequently tunnel metrics are updated
|
// MetricsUpdateFreq is the command line flag to define how frequently tunnel metrics are updated
|
||||||
MetricsUpdateFreq = "metrics-update-freq"
|
MetricsUpdateFreq = "metrics-update-freq"
|
||||||
|
|
||||||
|
// ApiURL is the command line flag used to define the base URL of the API
|
||||||
|
ApiURL = "api-url"
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,9 +23,7 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/management"
|
"github.com/cloudflare/cloudflared/management"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var buildInfo *cliutil.BuildInfo
|
||||||
buildInfo *cliutil.BuildInfo
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init(bi *cliutil.BuildInfo) {
|
func Init(bi *cliutil.BuildInfo) {
|
||||||
buildInfo = bi
|
buildInfo = bi
|
||||||
|
@ -56,7 +54,7 @@ func managementTokenCommand(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var tokenResponse = struct {
|
tokenResponse := struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}{Token: token}
|
}{Token: token}
|
||||||
|
|
||||||
|
@ -231,7 +229,7 @@ func getManagementToken(c *cli.Context, log *zerolog.Logger) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := userCreds.Client(c.String("api-url"), buildInfo.UserAgent(), log)
|
client, err := userCreds.Client(c.String(cfdflags.ApiURL), buildInfo.UserAgent(), log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ var (
|
||||||
"hostname",
|
"hostname",
|
||||||
"id",
|
"id",
|
||||||
cfdflags.LBPool,
|
cfdflags.LBPool,
|
||||||
"api-url",
|
cfdflags.ApiURL,
|
||||||
cfdflags.MetricsUpdateFreq,
|
cfdflags.MetricsUpdateFreq,
|
||||||
cfdflags.Tag,
|
cfdflags.Tag,
|
||||||
"heartbeat-interval",
|
"heartbeat-interval",
|
||||||
|
@ -716,7 +716,7 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
}),
|
}),
|
||||||
altsrc.NewStringFlag(&cli.StringFlag{
|
altsrc.NewStringFlag(&cli.StringFlag{
|
||||||
Name: "api-url",
|
Name: cfdflags.ApiURL,
|
||||||
Usage: "Base URL for Cloudflare API v4",
|
Usage: "Base URL for Cloudflare API v4",
|
||||||
EnvVars: []string{"TUNNEL_API_URL"},
|
EnvVars: []string{"TUNNEL_API_URL"},
|
||||||
Value: "https://api.cloudflare.com/client/v4",
|
Value: "https://api.cloudflare.com/client/v4",
|
||||||
|
|
|
@ -34,6 +34,7 @@ import (
|
||||||
const (
|
const (
|
||||||
secretValue = "*****"
|
secretValue = "*****"
|
||||||
icmpFunnelTimeout = time.Second * 10
|
icmpFunnelTimeout = time.Second * 10
|
||||||
|
fedRampRegion = "fed" // const string denoting the region used to connect to FEDRamp servers
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -208,13 +209,27 @@ func prepareTunnelConfig(
|
||||||
log.Warn().Str("edgeIPVersion", edgeIPVersion.String()).Err(err).Msg("Overriding edge-ip-version")
|
log.Warn().Str("edgeIPVersion", edgeIPVersion.String()).Err(err).Msg("Overriding edge-ip-version")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
region := c.String(flags.Region)
|
||||||
|
endpoint := namedTunnel.Credentials.Endpoint
|
||||||
|
var resolvedRegion string
|
||||||
|
// set resolvedRegion to either the region passed as argument
|
||||||
|
// or to the endpoint in the credentials.
|
||||||
|
// Region and endpoint are interchangeable
|
||||||
|
if region != "" && endpoint != "" {
|
||||||
|
return nil, nil, fmt.Errorf("region provided with a token that has an endpoint")
|
||||||
|
} else if region != "" {
|
||||||
|
resolvedRegion = region
|
||||||
|
} else if endpoint != "" {
|
||||||
|
resolvedRegion = endpoint
|
||||||
|
}
|
||||||
|
|
||||||
tunnelConfig := &supervisor.TunnelConfig{
|
tunnelConfig := &supervisor.TunnelConfig{
|
||||||
GracePeriod: gracePeriod,
|
GracePeriod: gracePeriod,
|
||||||
ReplaceExisting: c.Bool(flags.Force),
|
ReplaceExisting: c.Bool(flags.Force),
|
||||||
OSArch: info.OSArch(),
|
OSArch: info.OSArch(),
|
||||||
ClientID: clientID.String(),
|
ClientID: clientID.String(),
|
||||||
EdgeAddrs: c.StringSlice(flags.Edge),
|
EdgeAddrs: c.StringSlice(flags.Edge),
|
||||||
Region: c.String(flags.Region),
|
Region: resolvedRegion,
|
||||||
EdgeIPVersion: edgeIPVersion,
|
EdgeIPVersion: edgeIPVersion,
|
||||||
EdgeBindAddr: edgeBindAddr,
|
EdgeBindAddr: edgeBindAddr,
|
||||||
HAConnections: c.Int(flags.HaConnections),
|
HAConnections: c.Int(flags.HaConnections),
|
||||||
|
|
|
@ -67,7 +67,7 @@ func login(c *cli.Context) error {
|
||||||
|
|
||||||
path, ok, err := checkForExistingCert()
|
path, ok, err := checkForExistingCert()
|
||||||
if ok {
|
if ok {
|
||||||
fmt.Fprintf(os.Stdout, "You have an existing certificate at %s which login would overwrite.\nIf this is intentional, please move or delete that file then run this command again.\n", path)
|
log.Error().Err(err).Msgf("You have an existing certificate at %s which login would overwrite.\nIf this is intentional, please move or delete that file then run this command again.\n", path)
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -78,7 +78,8 @@ func login(c *cli.Context) error {
|
||||||
callbackStoreURL = c.String(callbackURLParamName)
|
callbackStoreURL = c.String(callbackURLParamName)
|
||||||
)
|
)
|
||||||
|
|
||||||
if c.Bool(fedRAMPParamName) {
|
isFEDRamp := c.Bool(fedRAMPParamName)
|
||||||
|
if isFEDRamp {
|
||||||
baseloginURL = fedBaseLoginURL
|
baseloginURL = fedBaseLoginURL
|
||||||
callbackStoreURL = fedCallbackStoreURL
|
callbackStoreURL = fedCallbackStoreURL
|
||||||
}
|
}
|
||||||
|
@ -99,7 +100,23 @@ func login(c *cli.Context) error {
|
||||||
log,
|
log,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to write the certificate due to the following error:\n%v\n\nYour browser will download the certificate instead. You will have to manually\ncopy it to the following path:\n\n%s\n", err, path)
|
log.Error().Err(err).Msgf("Failed to write the certificate.\n\nYour browser will download the certificate instead. You will have to manually\ncopy it to the following path:\n\n%s\n", path)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := credentials.DecodeOriginCert(resourceData)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to decode origin certificate")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isFEDRamp {
|
||||||
|
cert.Endpoint = credentials.FedEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceData, err = cert.EncodeOriginCert()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to encode origin certificate")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +124,7 @@ func login(c *cli.Context) error {
|
||||||
return errors.Wrap(err, fmt.Sprintf("error writing cert to %s", path))
|
return errors.Wrap(err, fmt.Sprintf("error writing cert to %s", path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(os.Stdout, "You have successfully logged in.\nIf you wish to copy your credentials to a server, they have been saved to:\n%s\n", path)
|
log.Info().Msgf("You have successfully logged in.\nIf you wish to copy your credentials to a server, they have been saved to:\n%s\n", path)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/logger"
|
"github.com/cloudflare/cloudflared/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const fedRampBaseApiURL = "https://api.fed.cloudflare.com/client/v4"
|
||||||
|
|
||||||
type invalidJSONCredentialError struct {
|
type invalidJSONCredentialError struct {
|
||||||
err error
|
err error
|
||||||
path string
|
path string
|
||||||
|
@ -65,7 +67,16 @@ func (sc *subcommandContext) client() (cfapi.Client, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sc.tunnelstoreClient, err = cred.Client(sc.c.String("api-url"), buildInfo.UserAgent(), sc.log)
|
|
||||||
|
var apiURL string
|
||||||
|
if cred.IsFEDEndpoint() {
|
||||||
|
sc.log.Info().Str("api-url", fedRampBaseApiURL).Msg("using fedramp base api")
|
||||||
|
apiURL = fedRampBaseApiURL
|
||||||
|
} else {
|
||||||
|
apiURL = sc.c.String(cfdflags.ApiURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
sc.tunnelstoreClient, err = cred.Client(apiURL, buildInfo.UserAgent(), sc.log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ type Credentials struct {
|
||||||
AccountTag string
|
AccountTag string
|
||||||
TunnelSecret []byte
|
TunnelSecret []byte
|
||||||
TunnelID uuid.UUID
|
TunnelID uuid.UUID
|
||||||
|
Endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Credentials) Auth() pogs.TunnelAuth {
|
func (c *Credentials) Auth() pogs.TunnelAuth {
|
||||||
|
@ -74,13 +75,16 @@ type TunnelToken struct {
|
||||||
AccountTag string `json:"a"`
|
AccountTag string `json:"a"`
|
||||||
TunnelSecret []byte `json:"s"`
|
TunnelSecret []byte `json:"s"`
|
||||||
TunnelID uuid.UUID `json:"t"`
|
TunnelID uuid.UUID `json:"t"`
|
||||||
|
Endpoint string `json:"e,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TunnelToken) Credentials() Credentials {
|
func (t TunnelToken) Credentials() Credentials {
|
||||||
|
// nolint: gosimple
|
||||||
return Credentials{
|
return Credentials{
|
||||||
AccountTag: t.AccountTag,
|
AccountTag: t.AccountTag,
|
||||||
TunnelSecret: t.TunnelSecret,
|
TunnelSecret: t.TunnelSecret,
|
||||||
TunnelID: t.TunnelID,
|
TunnelID: t.TunnelID,
|
||||||
|
Endpoint: t.Endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
logFieldOriginCertPath = "originCertPath"
|
logFieldOriginCertPath = "originCertPath"
|
||||||
|
FedEndpoint = "fed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
|
@ -32,6 +33,10 @@ func (c User) CertPath() string {
|
||||||
return c.certPath
|
return c.certPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c User) IsFEDEndpoint() bool {
|
||||||
|
return c.cert.Endpoint == FedEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
// Client uses the user credentials to create a Cloudflare API client
|
// Client uses the user credentials to create a Cloudflare API client
|
||||||
func (c *User) Client(apiURL string, userAgent string, log *zerolog.Logger) (cfapi.Client, error) {
|
func (c *User) Client(apiURL string, userAgent string, log *zerolog.Logger) (cfapi.Client, error) {
|
||||||
if apiURL == "" {
|
if apiURL == "" {
|
||||||
|
@ -45,7 +50,6 @@ func (c *User) Client(apiURL string, userAgent string, log *zerolog.Logger) (cfa
|
||||||
userAgent,
|
userAgent,
|
||||||
log,
|
log,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package credentials
|
package credentials
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
@ -17,16 +19,28 @@ const (
|
||||||
DefaultCredentialFile = "cert.pem"
|
DefaultCredentialFile = "cert.pem"
|
||||||
)
|
)
|
||||||
|
|
||||||
type namedTunnelToken struct {
|
type OriginCert struct {
|
||||||
ZoneID string `json:"zoneID"`
|
ZoneID string `json:"zoneID"`
|
||||||
AccountID string `json:"accountID"`
|
AccountID string `json:"accountID"`
|
||||||
APIToken string `json:"apiToken"`
|
APIToken string `json:"apiToken"`
|
||||||
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OriginCert struct {
|
func (oc *OriginCert) UnmarshalJSON(data []byte) error {
|
||||||
ZoneID string
|
var aux struct {
|
||||||
APIToken string
|
ZoneID string `json:"zoneID"`
|
||||||
AccountID string
|
AccountID string `json:"accountID"`
|
||||||
|
APIToken string `json:"apiToken"`
|
||||||
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &aux); err != nil {
|
||||||
|
return fmt.Errorf("error parsing OriginCert: %v", err)
|
||||||
|
}
|
||||||
|
oc.ZoneID = aux.ZoneID
|
||||||
|
oc.AccountID = aux.AccountID
|
||||||
|
oc.APIToken = aux.APIToken
|
||||||
|
oc.Endpoint = strings.ToLower(aux.Endpoint)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindDefaultOriginCertPath returns the first path that contains a cert.pem file. If none of the
|
// FindDefaultOriginCertPath returns the first path that contains a cert.pem file. If none of the
|
||||||
|
@ -41,40 +55,56 @@ func FindDefaultOriginCertPath() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DecodeOriginCert(blocks []byte) (*OriginCert, error) {
|
||||||
|
return decodeOriginCert(blocks)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cert *OriginCert) EncodeOriginCert() ([]byte, error) {
|
||||||
|
if cert == nil {
|
||||||
|
return nil, fmt.Errorf("originCert cannot be nil")
|
||||||
|
}
|
||||||
|
buffer, err := json.Marshal(cert)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("originCert marshal failed: %v", err)
|
||||||
|
}
|
||||||
|
block := pem.Block{
|
||||||
|
Type: "ARGO TUNNEL TOKEN",
|
||||||
|
Headers: map[string]string{},
|
||||||
|
Bytes: buffer,
|
||||||
|
}
|
||||||
|
var out bytes.Buffer
|
||||||
|
err = pem.Encode(&out, &block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("pem encoding failed: %v", err)
|
||||||
|
}
|
||||||
|
return out.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func decodeOriginCert(blocks []byte) (*OriginCert, error) {
|
func decodeOriginCert(blocks []byte) (*OriginCert, error) {
|
||||||
if len(blocks) == 0 {
|
if len(blocks) == 0 {
|
||||||
return nil, fmt.Errorf("Cannot decode empty certificate")
|
return nil, fmt.Errorf("cannot decode empty certificate")
|
||||||
}
|
}
|
||||||
originCert := OriginCert{}
|
originCert := OriginCert{}
|
||||||
block, rest := pem.Decode(blocks)
|
block, rest := pem.Decode(blocks)
|
||||||
for {
|
for block != nil {
|
||||||
if block == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
switch block.Type {
|
switch block.Type {
|
||||||
case "PRIVATE KEY", "CERTIFICATE":
|
case "PRIVATE KEY", "CERTIFICATE":
|
||||||
// this is for legacy purposes.
|
// this is for legacy purposes.
|
||||||
break
|
|
||||||
case "ARGO TUNNEL TOKEN":
|
case "ARGO TUNNEL TOKEN":
|
||||||
if originCert.ZoneID != "" || originCert.APIToken != "" {
|
if originCert.ZoneID != "" || originCert.APIToken != "" {
|
||||||
return nil, fmt.Errorf("Found multiple tokens in the certificate")
|
return nil, fmt.Errorf("found multiple tokens in the certificate")
|
||||||
}
|
}
|
||||||
// The token is a string,
|
// The token is a string,
|
||||||
// Try the newer JSON format
|
// Try the newer JSON format
|
||||||
ntt := namedTunnelToken{}
|
_ = json.Unmarshal(block.Bytes, &originCert)
|
||||||
if err := json.Unmarshal(block.Bytes, &ntt); err == nil {
|
|
||||||
originCert.ZoneID = ntt.ZoneID
|
|
||||||
originCert.APIToken = ntt.APIToken
|
|
||||||
originCert.AccountID = ntt.AccountID
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Unknown block %s in the certificate", block.Type)
|
return nil, fmt.Errorf("unknown block %s in the certificate", block.Type)
|
||||||
}
|
}
|
||||||
block, rest = pem.Decode(rest)
|
block, rest = pem.Decode(rest)
|
||||||
}
|
}
|
||||||
|
|
||||||
if originCert.ZoneID == "" || originCert.APIToken == "" {
|
if originCert.ZoneID == "" || originCert.APIToken == "" {
|
||||||
return nil, fmt.Errorf("Missing token in the certificate")
|
return nil, fmt.Errorf("missing token in the certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &originCert, nil
|
return &originCert, nil
|
||||||
|
|
|
@ -16,27 +16,25 @@ const (
|
||||||
originCertFile = "cert.pem"
|
originCertFile = "cert.pem"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var nopLog = zerolog.Nop().With().Logger()
|
||||||
nopLog = zerolog.Nop().With().Logger()
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLoadOriginCert(t *testing.T) {
|
func TestLoadOriginCert(t *testing.T) {
|
||||||
cert, err := decodeOriginCert([]byte{})
|
cert, err := decodeOriginCert([]byte{})
|
||||||
assert.Equal(t, fmt.Errorf("Cannot decode empty certificate"), err)
|
assert.Equal(t, fmt.Errorf("cannot decode empty certificate"), err)
|
||||||
assert.Nil(t, cert)
|
assert.Nil(t, cert)
|
||||||
|
|
||||||
blocks, err := os.ReadFile("test-cert-unknown-block.pem")
|
blocks, err := os.ReadFile("test-cert-unknown-block.pem")
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cert, err = decodeOriginCert(blocks)
|
cert, err = decodeOriginCert(blocks)
|
||||||
assert.Equal(t, fmt.Errorf("Unknown block RSA PRIVATE KEY in the certificate"), err)
|
assert.Equal(t, fmt.Errorf("unknown block RSA PRIVATE KEY in the certificate"), err)
|
||||||
assert.Nil(t, cert)
|
assert.Nil(t, cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJSONArgoTunnelTokenEmpty(t *testing.T) {
|
func TestJSONArgoTunnelTokenEmpty(t *testing.T) {
|
||||||
blocks, err := os.ReadFile("test-cert-no-token.pem")
|
blocks, err := os.ReadFile("test-cert-no-token.pem")
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cert, err := decodeOriginCert(blocks)
|
cert, err := decodeOriginCert(blocks)
|
||||||
assert.Equal(t, fmt.Errorf("Missing token in the certificate"), err)
|
assert.Equal(t, fmt.Errorf("missing token in the certificate"), err)
|
||||||
assert.Nil(t, cert)
|
assert.Nil(t, cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,51 +50,21 @@ func TestJSONArgoTunnelToken(t *testing.T) {
|
||||||
|
|
||||||
func CloudflareTunnelTokenTest(t *testing.T, path string) {
|
func CloudflareTunnelTokenTest(t *testing.T, path string) {
|
||||||
blocks, err := os.ReadFile(path)
|
blocks, err := os.ReadFile(path)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cert, err := decodeOriginCert(blocks)
|
cert, err := decodeOriginCert(blocks)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, cert)
|
assert.NotNil(t, cert)
|
||||||
assert.Equal(t, "7b0a4d77dfb881c1a3b7d61ea9443e19", cert.ZoneID)
|
assert.Equal(t, "7b0a4d77dfb881c1a3b7d61ea9443e19", cert.ZoneID)
|
||||||
key := "test-service-key"
|
key := "test-service-key"
|
||||||
assert.Equal(t, key, cert.APIToken)
|
assert.Equal(t, key, cert.APIToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockFile struct {
|
|
||||||
path string
|
|
||||||
data []byte
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockFileSystem struct {
|
|
||||||
files map[string]mockFile
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockFileSystem(files ...mockFile) *mockFileSystem {
|
|
||||||
fs := mockFileSystem{map[string]mockFile{}}
|
|
||||||
for _, f := range files {
|
|
||||||
fs.files[f.path] = f
|
|
||||||
}
|
|
||||||
return &fs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fs *mockFileSystem) ReadFile(path string) ([]byte, error) {
|
|
||||||
if f, ok := fs.files[path]; ok {
|
|
||||||
return f.data, f.err
|
|
||||||
}
|
|
||||||
return nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fs *mockFileSystem) ValidFilePath(path string) bool {
|
|
||||||
_, exists := fs.files[path]
|
|
||||||
return exists
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFindOriginCert_Valid(t *testing.T) {
|
func TestFindOriginCert_Valid(t *testing.T) {
|
||||||
file, err := os.ReadFile("test-cloudflare-tunnel-cert-json.pem")
|
file, err := os.ReadFile("test-cloudflare-tunnel-cert-json.pem")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
certPath := path.Join(dir, originCertFile)
|
certPath := path.Join(dir, originCertFile)
|
||||||
os.WriteFile(certPath, file, fs.ModePerm)
|
_ = os.WriteFile(certPath, file, fs.ModePerm)
|
||||||
path, err := FindOriginCert(certPath, &nopLog)
|
path, err := FindOriginCert(certPath, &nopLog)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, certPath, path)
|
require.Equal(t, certPath, path)
|
||||||
|
@ -108,3 +76,28 @@ func TestFindOriginCert_Missing(t *testing.T) {
|
||||||
_, err := FindOriginCert(certPath, &nopLog)
|
_, err := FindOriginCert(certPath, &nopLog)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncodeDecodeOriginCert(t *testing.T) {
|
||||||
|
cert := OriginCert{
|
||||||
|
ZoneID: "zone",
|
||||||
|
AccountID: "account",
|
||||||
|
APIToken: "token",
|
||||||
|
Endpoint: "FED",
|
||||||
|
}
|
||||||
|
blocks, err := cert.EncodeOriginCert()
|
||||||
|
require.NoError(t, err)
|
||||||
|
decodedCert, err := DecodeOriginCert(blocks)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, cert)
|
||||||
|
assert.Equal(t, "zone", decodedCert.ZoneID)
|
||||||
|
assert.Equal(t, "account", decodedCert.AccountID)
|
||||||
|
assert.Equal(t, "token", decodedCert.APIToken)
|
||||||
|
assert.Equal(t, FedEndpoint, decodedCert.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncodeDecodeNilOriginCert(t *testing.T) {
|
||||||
|
var cert *OriginCert
|
||||||
|
blocks, err := cert.EncodeOriginCert()
|
||||||
|
assert.Equal(t, fmt.Errorf("originCert cannot be nil"), err)
|
||||||
|
require.Nil(t, blocks)
|
||||||
|
}
|
||||||
|
|
|
@ -87,3 +87,4 @@ M2i4QoOFcSKIG+v4SuvgEJHgG8vGvxh2qlSxnMWuPV+7/1P5ATLqDj1PlKms+BNR
|
||||||
y7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz
|
y7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz
|
||||||
uQicoQq3yzeQh20wtrtaXzTNmA==
|
uQicoQq3yzeQh20wtrtaXzTNmA==
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
|
@ -247,9 +247,7 @@ func (s *Supervisor) startFirstTunnel(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
connectedSignal *signal.Signal,
|
connectedSignal *signal.Signal,
|
||||||
) {
|
) {
|
||||||
var (
|
var err error
|
||||||
err error
|
|
||||||
)
|
|
||||||
const firstConnIndex = 0
|
const firstConnIndex = 0
|
||||||
isStaticEdge := len(s.config.EdgeAddrs) > 0
|
isStaticEdge := len(s.config.EdgeAddrs) > 0
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -300,9 +298,7 @@ func (s *Supervisor) startTunnel(
|
||||||
index int,
|
index int,
|
||||||
connectedSignal *signal.Signal,
|
connectedSignal *signal.Signal,
|
||||||
) {
|
) {
|
||||||
var (
|
var err error
|
||||||
err error
|
|
||||||
)
|
|
||||||
defer func() {
|
defer func() {
|
||||||
s.tunnelErrors <- tunnelError{index: index, err: err}
|
s.tunnelErrors <- tunnelError{index: index, err: err}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -70,7 +70,6 @@ func RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string,
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourceData, nil
|
return resourceData, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildRequestURL creates a request suitable for a resource transfer.
|
// BuildRequestURL creates a request suitable for a resource transfer.
|
||||||
|
|
Loading…
Reference in New Issue