mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 00:59:58 +00:00
TUN-3019: Remove declarative tunnel entry code
This commit is contained in:
@@ -1,775 +0,0 @@
|
||||
package pogs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/h2mux"
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
"github.com/cloudflare/cloudflared/originservice"
|
||||
"github.com/cloudflare/cloudflared/tlsconfig"
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
capnp "zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/pogs"
|
||||
"zombiezen.com/go/capnproto2/rpc"
|
||||
"zombiezen.com/go/capnproto2/server"
|
||||
)
|
||||
|
||||
///
|
||||
/// Structs
|
||||
///
|
||||
|
||||
// ClientConfig is a collection of FallibleConfig that determines how cloudflared should function
|
||||
type ClientConfig struct {
|
||||
Version Version
|
||||
SupervisorConfig *SupervisorConfig
|
||||
EdgeConnectionConfig *EdgeConnectionConfig
|
||||
DoHProxyConfigs []*DoHProxyConfig `capnp:"dohProxyConfigs"`
|
||||
ReverseProxyConfigs []*ReverseProxyConfig
|
||||
}
|
||||
|
||||
func (c *ClientConfig) MarshalBytes() ([]byte, error) {
|
||||
msg, firstSeg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
capnpEntity, err := tunnelrpc.NewRootClientConfig(firstSeg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = MarshalClientConfig(capnpEntity, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msg.Marshal()
|
||||
}
|
||||
|
||||
func UnmarshalClientConfigFromBytes(clientConfigBytes []byte) (*ClientConfig, error) {
|
||||
msg, err := capnp.Unmarshal(clientConfigBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
capnpClientConfig, err := tunnelrpc.ReadRootClientConfig(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pogsClientConfig, err := UnmarshalClientConfig(capnpClientConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pogsClientConfig, nil
|
||||
}
|
||||
|
||||
// Version type models the version of a ClientConfig
|
||||
type Version uint64
|
||||
|
||||
func InitVersion() Version {
|
||||
return Version(0)
|
||||
}
|
||||
|
||||
func (v Version) IsNewerOrEqual(comparedVersion Version) bool {
|
||||
return v >= comparedVersion
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
return fmt.Sprintf("Version: %d", v)
|
||||
}
|
||||
|
||||
// FallibleConfig is an interface implemented by configs that cloudflared might not be able to apply
|
||||
//go-sumtype:decl FallibleConfig
|
||||
type FallibleConfig interface {
|
||||
FailReason(err error) string
|
||||
isFallibleConfig()
|
||||
}
|
||||
|
||||
// SupervisorConfig specifies config of components managed by Supervisor other than ConnectionManager
|
||||
type SupervisorConfig struct {
|
||||
AutoUpdateFrequency time.Duration
|
||||
MetricsUpdateFrequency time.Duration
|
||||
GracePeriod time.Duration
|
||||
}
|
||||
|
||||
// FailReason impelents FallibleConfig interface for SupervisorConfig
|
||||
func (sc *SupervisorConfig) FailReason(err error) string {
|
||||
return fmt.Sprintf("Cannot apply SupervisorConfig, err: %v", err)
|
||||
}
|
||||
|
||||
func (_ *SupervisorConfig) isFallibleConfig() {}
|
||||
|
||||
// EdgeConnectionConfig specifies what parameters and how may connections should ConnectionManager establish with edge
|
||||
type EdgeConnectionConfig struct {
|
||||
NumHAConnections uint8
|
||||
HeartbeatInterval time.Duration
|
||||
Timeout time.Duration
|
||||
MaxFailedHeartbeats uint64
|
||||
UserCredentialPath string
|
||||
}
|
||||
|
||||
// FailReason impelents FallibleConfig interface for EdgeConnectionConfig
|
||||
func (cmc *EdgeConnectionConfig) FailReason(err error) string {
|
||||
return fmt.Sprintf("Cannot apply EdgeConnectionConfig, err: %v", err)
|
||||
}
|
||||
|
||||
func (_ *EdgeConnectionConfig) isFallibleConfig() {}
|
||||
|
||||
// DoHProxyConfig is configuration for DNS over HTTPS service
|
||||
type DoHProxyConfig struct {
|
||||
ListenHost string
|
||||
ListenPort uint16
|
||||
Upstreams []string
|
||||
}
|
||||
|
||||
// FailReason impelents FallibleConfig interface for DoHProxyConfig
|
||||
func (dpc *DoHProxyConfig) FailReason(err error) string {
|
||||
return fmt.Sprintf("Cannot apply DoHProxyConfig, err: %v", err)
|
||||
}
|
||||
|
||||
func (_ *DoHProxyConfig) isFallibleConfig() {}
|
||||
|
||||
// ReverseProxyConfig how and for what hostnames can this cloudflared proxy
|
||||
type ReverseProxyConfig struct {
|
||||
TunnelHostname h2mux.TunnelHostname
|
||||
OriginConfig OriginConfig
|
||||
Retries uint64
|
||||
ConnectionTimeout time.Duration
|
||||
CompressionQuality uint64
|
||||
}
|
||||
|
||||
func NewReverseProxyConfig(
|
||||
tunnelHostname string,
|
||||
originConfig OriginConfig,
|
||||
retries uint64,
|
||||
connectionTimeout time.Duration,
|
||||
compressionQuality uint64,
|
||||
) (*ReverseProxyConfig, error) {
|
||||
if originConfig == nil {
|
||||
return nil, fmt.Errorf("NewReverseProxyConfig: originConfigUnmarshaler was null")
|
||||
}
|
||||
return &ReverseProxyConfig{
|
||||
TunnelHostname: h2mux.TunnelHostname(tunnelHostname),
|
||||
OriginConfig: originConfig,
|
||||
Retries: retries,
|
||||
ConnectionTimeout: connectionTimeout,
|
||||
CompressionQuality: compressionQuality,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FailReason impelents FallibleConfig interface for ReverseProxyConfig
|
||||
func (rpc *ReverseProxyConfig) FailReason(err error) string {
|
||||
return fmt.Sprintf("Cannot apply ReverseProxyConfig, err: %v", err)
|
||||
}
|
||||
|
||||
func (_ *ReverseProxyConfig) isFallibleConfig() {}
|
||||
|
||||
//go-sumtype:decl OriginConfig
|
||||
type OriginConfig interface {
|
||||
// Service returns a OriginService used to proxy to the origin
|
||||
Service(logger.Service) (originservice.OriginService, error)
|
||||
// go-sumtype requires at least one unexported method, otherwise it will complain that interface is not sealed
|
||||
isOriginConfig()
|
||||
}
|
||||
|
||||
type HTTPOriginConfig struct {
|
||||
URLString string `capnp:"urlString"`
|
||||
TCPKeepAlive time.Duration `capnp:"tcpKeepAlive"`
|
||||
DialDualStack bool
|
||||
TLSHandshakeTimeout time.Duration `capnp:"tlsHandshakeTimeout"`
|
||||
TLSVerify bool `capnp:"tlsVerify"`
|
||||
OriginCAPool string
|
||||
OriginServerName string
|
||||
MaxIdleConnections uint64
|
||||
IdleConnectionTimeout time.Duration
|
||||
ProxyConnectionTimeout time.Duration
|
||||
ExpectContinueTimeout time.Duration
|
||||
ChunkedEncoding bool
|
||||
}
|
||||
|
||||
func (hc *HTTPOriginConfig) Service(logger logger.Service) (originservice.OriginService, error) {
|
||||
rootCAs, err := tlsconfig.LoadCustomOriginCA(hc.OriginCAPool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialer := &net.Dialer{
|
||||
Timeout: hc.ProxyConnectionTimeout,
|
||||
KeepAlive: hc.TCPKeepAlive,
|
||||
}
|
||||
if !hc.DialDualStack {
|
||||
dialer.FallbackDelay = -1
|
||||
}
|
||||
dialContext := dialer.DialContext
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialContext,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: rootCAs,
|
||||
ServerName: hc.OriginServerName,
|
||||
InsecureSkipVerify: hc.TLSVerify,
|
||||
},
|
||||
TLSHandshakeTimeout: hc.TLSHandshakeTimeout,
|
||||
MaxIdleConns: int(hc.MaxIdleConnections),
|
||||
IdleConnTimeout: hc.IdleConnectionTimeout,
|
||||
ExpectContinueTimeout: hc.ExpectContinueTimeout,
|
||||
}
|
||||
url, err := url.Parse(hc.URLString)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%s is not a valid URL", hc.URLString)
|
||||
}
|
||||
if url.Scheme == "unix" {
|
||||
transport.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {
|
||||
return dialContext(ctx, "unix", url.Host)
|
||||
}
|
||||
}
|
||||
return originservice.NewHTTPService(transport, url, hc.ChunkedEncoding), nil
|
||||
}
|
||||
|
||||
func (*HTTPOriginConfig) isOriginConfig() {}
|
||||
|
||||
type WebSocketOriginConfig struct {
|
||||
URLString string `capnp:"urlString"`
|
||||
TLSVerify bool `capnp:"tlsVerify"`
|
||||
OriginCAPool string
|
||||
OriginServerName string
|
||||
}
|
||||
|
||||
func (wsc *WebSocketOriginConfig) Service(logger logger.Service) (originservice.OriginService, error) {
|
||||
rootCAs, err := tlsconfig.LoadCustomOriginCA(wsc.OriginCAPool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
RootCAs: rootCAs,
|
||||
ServerName: wsc.OriginServerName,
|
||||
InsecureSkipVerify: wsc.TLSVerify,
|
||||
}
|
||||
|
||||
url, err := url.Parse(wsc.URLString)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%s is not a valid URL", wsc.URLString)
|
||||
}
|
||||
return originservice.NewWebSocketService(tlsConfig, url, logger)
|
||||
}
|
||||
|
||||
func (*WebSocketOriginConfig) isOriginConfig() {}
|
||||
|
||||
type HelloWorldOriginConfig struct{}
|
||||
|
||||
func (*HelloWorldOriginConfig) Service(logger logger.Service) (originservice.OriginService, error) {
|
||||
helloCert, err := tlsconfig.GetHelloCertificateX509()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get Hello World server certificate")
|
||||
}
|
||||
rootCAs := x509.NewCertPool()
|
||||
rootCAs.AddCert(helloCert)
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).DialContext,
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: rootCAs,
|
||||
},
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
return originservice.NewHelloWorldService(transport, logger)
|
||||
}
|
||||
|
||||
func (*HelloWorldOriginConfig) isOriginConfig() {}
|
||||
|
||||
/*
|
||||
* Boilerplate to convert between these structs and the primitive structs
|
||||
* generated by capnp-go.
|
||||
* Mnemonics for variable names in this section:
|
||||
* - `p` is for POGS (plain old Go struct)
|
||||
* - `s` (and `ss`) is for "capnp.Struct", which is the fundamental type
|
||||
* underlying the capnp-go data structures.
|
||||
*/
|
||||
|
||||
func MarshalClientConfig(s tunnelrpc.ClientConfig, p *ClientConfig) error {
|
||||
s.SetVersion(uint64(p.Version))
|
||||
|
||||
supervisorConfig, err := s.NewSupervisorConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get SupervisorConfig")
|
||||
}
|
||||
if err = MarshalSupervisorConfig(supervisorConfig, p.SupervisorConfig); err != nil {
|
||||
return errors.Wrap(err, "MarshalSupervisorConfig error")
|
||||
}
|
||||
|
||||
edgeConnectionConfig, err := s.NewEdgeConnectionConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get EdgeConnectionConfig")
|
||||
}
|
||||
if err := MarshalEdgeConnectionConfig(edgeConnectionConfig, p.EdgeConnectionConfig); err != nil {
|
||||
return errors.Wrap(err, "MarshalEdgeConnectionConfig error")
|
||||
}
|
||||
|
||||
if err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs); err != nil {
|
||||
return errors.Wrap(err, "marshalDoHProxyConfigs error")
|
||||
}
|
||||
if err := marshalReverseProxyConfigs(s, p.ReverseProxyConfigs); err != nil {
|
||||
return errors.Wrap(err, "marshalReverseProxyConfigs error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MarshalSupervisorConfig(s tunnelrpc.SupervisorConfig, p *SupervisorConfig) error {
|
||||
if err := pogs.Insert(tunnelrpc.SupervisorConfig_TypeID, s.Struct, p); err != nil {
|
||||
return errors.Wrap(err, "failed to insert SupervisorConfig")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MarshalEdgeConnectionConfig(s tunnelrpc.EdgeConnectionConfig, p *EdgeConnectionConfig) error {
|
||||
if err := pogs.Insert(tunnelrpc.EdgeConnectionConfig_TypeID, s.Struct, p); err != nil {
|
||||
return errors.Wrap(err, "failed to insert EdgeConnectionConfig")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func marshalDoHProxyConfigs(s tunnelrpc.ClientConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
||||
capnpList, err := s.NewDohProxyConfigs(int32(len(dohProxyConfigs)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, unmarshalledConfig := range dohProxyConfigs {
|
||||
err := MarshalDoHProxyConfig(capnpList.At(i), unmarshalledConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func marshalReverseProxyConfigs(s tunnelrpc.ClientConfig, reverseProxyConfigs []*ReverseProxyConfig) error {
|
||||
capnpList, err := s.NewReverseProxyConfigs(int32(len(reverseProxyConfigs)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, unmarshalledConfig := range reverseProxyConfigs {
|
||||
err := MarshalReverseProxyConfig(capnpList.At(i), unmarshalledConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalClientConfig(s tunnelrpc.ClientConfig) (*ClientConfig, error) {
|
||||
p := new(ClientConfig)
|
||||
p.Version = Version(s.Version())
|
||||
|
||||
supervisorConfig, err := s.SupervisorConfig()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get SupervisorConfig")
|
||||
}
|
||||
p.SupervisorConfig, err = UnmarshalSupervisorConfig(supervisorConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UnmarshalSupervisorConfig error")
|
||||
}
|
||||
|
||||
edgeConnectionConfig, err := s.EdgeConnectionConfig()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get ConnectionManagerConfig")
|
||||
}
|
||||
p.EdgeConnectionConfig, err = UnmarshalEdgeConnectionConfig(edgeConnectionConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UnmarshalConnectionManagerConfig error")
|
||||
}
|
||||
|
||||
p.DoHProxyConfigs, err = unmarshalDoHProxyConfigs(s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshalDoHProxyConfigs error")
|
||||
}
|
||||
|
||||
p.ReverseProxyConfigs, err = unmarshalReverseProxyConfigs(s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshalReverseProxyConfigs error")
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func UnmarshalSupervisorConfig(s tunnelrpc.SupervisorConfig) (*SupervisorConfig, error) {
|
||||
p := new(SupervisorConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.SupervisorConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func UnmarshalEdgeConnectionConfig(s tunnelrpc.EdgeConnectionConfig) (*EdgeConnectionConfig, error) {
|
||||
p := new(EdgeConnectionConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.EdgeConnectionConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func unmarshalDoHProxyConfigs(s tunnelrpc.ClientConfig) ([]*DoHProxyConfig, error) {
|
||||
var result []*DoHProxyConfig
|
||||
marshalledDoHProxyConfigs, err := s.DohProxyConfigs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < marshalledDoHProxyConfigs.Len(); i++ {
|
||||
ss := marshalledDoHProxyConfigs.At(i)
|
||||
dohProxyConfig, err := UnmarshalDoHProxyConfig(ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, dohProxyConfig)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func unmarshalReverseProxyConfigs(s tunnelrpc.ClientConfig) ([]*ReverseProxyConfig, error) {
|
||||
var result []*ReverseProxyConfig
|
||||
marshalledReverseProxyConfigs, err := s.ReverseProxyConfigs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < marshalledReverseProxyConfigs.Len(); i++ {
|
||||
ss := marshalledReverseProxyConfigs.At(i)
|
||||
reverseProxyConfig, err := UnmarshalReverseProxyConfig(ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, reverseProxyConfig)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func MarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult, p *UseConfigurationResult) error {
|
||||
capnpList, err := s.NewFailedConfigs(int32(len(p.FailedConfigs)))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Cannot create new FailedConfigs")
|
||||
}
|
||||
for i, unmarshalledFailedConfig := range p.FailedConfigs {
|
||||
err := MarshalFailedConfig(capnpList.At(i), unmarshalledFailedConfig)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Cannot MarshalFailedConfig at index %d", i)
|
||||
}
|
||||
}
|
||||
s.SetSuccess(p.Success)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult) (*UseConfigurationResult, error) {
|
||||
p := new(UseConfigurationResult)
|
||||
var failedConfigs []*FailedConfig
|
||||
marshalledFailedConfigs, err := s.FailedConfigs()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get FailedConfigs")
|
||||
}
|
||||
for i := 0; i < marshalledFailedConfigs.Len(); i++ {
|
||||
ss := marshalledFailedConfigs.At(i)
|
||||
failedConfig, err := UnmarshalFailedConfig(ss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Cannot UnmarshalFailedConfig at index %d", i)
|
||||
}
|
||||
failedConfigs = append(failedConfigs, failedConfig)
|
||||
}
|
||||
p.FailedConfigs = failedConfigs
|
||||
p.Success = s.Success()
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func MarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig, p *DoHProxyConfig) error {
|
||||
return pogs.Insert(tunnelrpc.DoHProxyConfig_TypeID, s.Struct, p)
|
||||
}
|
||||
|
||||
func UnmarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig) (*DoHProxyConfig, error) {
|
||||
p := new(DoHProxyConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.DoHProxyConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyConfig) error {
|
||||
s.SetTunnelHostname(p.TunnelHostname.String())
|
||||
switch config := p.OriginConfig.(type) {
|
||||
case *HTTPOriginConfig:
|
||||
ss, err := s.OriginConfig().NewHttp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := MarshalHTTPOriginConfig(ss, config); err != nil {
|
||||
return err
|
||||
}
|
||||
case *WebSocketOriginConfig:
|
||||
ss, err := s.OriginConfig().NewWebsocket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := MarshalWebSocketOriginConfig(ss, config); err != nil {
|
||||
return err
|
||||
}
|
||||
case *HelloWorldOriginConfig:
|
||||
ss, err := s.OriginConfig().NewHelloWorld()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := MarshalHelloWorldOriginConfig(ss, config); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unknown type for config: %T", config)
|
||||
}
|
||||
s.SetRetries(p.Retries)
|
||||
s.SetConnectionTimeout(p.ConnectionTimeout.Nanoseconds())
|
||||
s.SetCompressionQuality(p.CompressionQuality)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyConfig, error) {
|
||||
p := new(ReverseProxyConfig)
|
||||
tunnelHostname, err := s.TunnelHostname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.TunnelHostname = h2mux.TunnelHostname(tunnelHostname)
|
||||
switch s.OriginConfig().Which() {
|
||||
case tunnelrpc.ReverseProxyConfig_originConfig_Which_http:
|
||||
ss, err := s.OriginConfig().Http()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config, err := UnmarshalHTTPOriginConfig(ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.OriginConfig = config
|
||||
case tunnelrpc.ReverseProxyConfig_originConfig_Which_websocket:
|
||||
ss, err := s.OriginConfig().Websocket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config, err := UnmarshalWebSocketOriginConfig(ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.OriginConfig = config
|
||||
case tunnelrpc.ReverseProxyConfig_originConfig_Which_helloWorld:
|
||||
ss, err := s.OriginConfig().HelloWorld()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config, err := UnmarshalHelloWorldOriginConfig(ss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.OriginConfig = config
|
||||
}
|
||||
p.Retries = s.Retries()
|
||||
p.ConnectionTimeout = time.Duration(s.ConnectionTimeout())
|
||||
p.CompressionQuality = s.CompressionQuality()
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func MarshalHTTPOriginConfig(s tunnelrpc.HTTPOriginConfig, p *HTTPOriginConfig) error {
|
||||
return pogs.Insert(tunnelrpc.HTTPOriginConfig_TypeID, s.Struct, p)
|
||||
}
|
||||
|
||||
func UnmarshalHTTPOriginConfig(s tunnelrpc.HTTPOriginConfig) (*HTTPOriginConfig, error) {
|
||||
p := new(HTTPOriginConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.HTTPOriginConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func MarshalWebSocketOriginConfig(s tunnelrpc.WebSocketOriginConfig, p *WebSocketOriginConfig) error {
|
||||
return pogs.Insert(tunnelrpc.WebSocketOriginConfig_TypeID, s.Struct, p)
|
||||
}
|
||||
|
||||
func UnmarshalWebSocketOriginConfig(s tunnelrpc.WebSocketOriginConfig) (*WebSocketOriginConfig, error) {
|
||||
p := new(WebSocketOriginConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.WebSocketOriginConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func MarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig, p *HelloWorldOriginConfig) error {
|
||||
return pogs.Insert(tunnelrpc.HelloWorldOriginConfig_TypeID, s.Struct, p)
|
||||
}
|
||||
|
||||
func UnmarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig) (*HelloWorldOriginConfig, error) {
|
||||
p := new(HelloWorldOriginConfig)
|
||||
err := pogs.Extract(p, tunnelrpc.HelloWorldOriginConfig_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
type ClientService interface {
|
||||
UseConfiguration(ctx context.Context, config *ClientConfig) (*UseConfigurationResult, error)
|
||||
}
|
||||
|
||||
type ClientService_PogsClient struct {
|
||||
Client capnp.Client
|
||||
Conn *rpc.Conn
|
||||
}
|
||||
|
||||
func (c *ClientService_PogsClient) Close() error {
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
func (c *ClientService_PogsClient) UseConfiguration(
|
||||
ctx context.Context,
|
||||
config *ClientConfig,
|
||||
) (*UseConfigurationResult, error) {
|
||||
client := tunnelrpc.ClientService{Client: c.Client}
|
||||
promise := client.UseConfiguration(ctx, func(p tunnelrpc.ClientService_useConfiguration_Params) error {
|
||||
clientServiceConfig, err := p.NewClientServiceConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return MarshalClientConfig(clientServiceConfig, config)
|
||||
})
|
||||
retval, err := promise.Result().Struct()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return UnmarshalUseConfigurationResult(retval)
|
||||
}
|
||||
|
||||
func ClientService_ServerToClient(s ClientService) tunnelrpc.ClientService {
|
||||
return tunnelrpc.ClientService_ServerToClient(ClientService_PogsImpl{s})
|
||||
}
|
||||
|
||||
type ClientService_PogsImpl struct {
|
||||
impl ClientService
|
||||
}
|
||||
|
||||
func (i ClientService_PogsImpl) UseConfiguration(p tunnelrpc.ClientService_useConfiguration) error {
|
||||
config, err := p.Params.ClientServiceConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Cannot get CloudflaredConfig parameter")
|
||||
}
|
||||
pogsConfig, err := UnmarshalClientConfig(config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Cannot unmarshal tunnelrpc.CloudflaredConfig to *CloudflaredConfig")
|
||||
}
|
||||
server.Ack(p.Options)
|
||||
userConfigResult, err := i.impl.UseConfiguration(p.Ctx, pogsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := p.Results.NewResult()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return MarshalUseConfigurationResult(result, userConfigResult)
|
||||
}
|
||||
|
||||
type UseConfigurationResult struct {
|
||||
Success bool
|
||||
FailedConfigs []*FailedConfig
|
||||
}
|
||||
|
||||
type FailedConfig struct {
|
||||
Config FallibleConfig
|
||||
Reason string
|
||||
}
|
||||
|
||||
func MarshalFailedConfig(s tunnelrpc.FailedConfig, p *FailedConfig) error {
|
||||
switch config := p.Config.(type) {
|
||||
case *SupervisorConfig:
|
||||
ss, err := s.Config().NewSupervisor()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = MarshalSupervisorConfig(ss, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *EdgeConnectionConfig:
|
||||
ss, err := s.Config().NewEdgeConnection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = MarshalEdgeConnectionConfig(ss, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *DoHProxyConfig:
|
||||
ss, err := s.Config().NewDoh()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = MarshalDoHProxyConfig(ss, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *ReverseProxyConfig:
|
||||
ss, err := s.Config().NewReverseProxy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = MarshalReverseProxyConfig(ss, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unknown type for Config: %T", config)
|
||||
}
|
||||
s.SetReason(p.Reason)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalFailedConfig(s tunnelrpc.FailedConfig) (*FailedConfig, error) {
|
||||
p := new(FailedConfig)
|
||||
switch s.Config().Which() {
|
||||
case tunnelrpc.FailedConfig_config_Which_supervisor:
|
||||
ss, err := s.Config().Supervisor()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get SupervisorConfig from Config")
|
||||
}
|
||||
config, err := UnmarshalSupervisorConfig(ss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot UnmarshalSupervisorConfig")
|
||||
}
|
||||
p.Config = config
|
||||
case tunnelrpc.FailedConfig_config_Which_edgeConnection:
|
||||
ss, err := s.Config().EdgeConnection()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get ConnectionManager from Config")
|
||||
}
|
||||
config, err := UnmarshalEdgeConnectionConfig(ss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot UnmarshalConnectionManagerConfig")
|
||||
}
|
||||
p.Config = config
|
||||
case tunnelrpc.FailedConfig_config_Which_doh:
|
||||
ss, err := s.Config().Doh()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get Doh from Config")
|
||||
}
|
||||
config, err := UnmarshalDoHProxyConfig(ss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot UnmarshalDoHProxyConfig")
|
||||
}
|
||||
p.Config = config
|
||||
case tunnelrpc.FailedConfig_config_Which_reverseProxy:
|
||||
ss, err := s.Config().ReverseProxy()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get ReverseProxy from Config")
|
||||
}
|
||||
config, err := UnmarshalReverseProxyConfig(ss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot UnmarshalReverseProxyConfig")
|
||||
}
|
||||
p.Config = config
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown type for FailedConfig: %v", s.Config().Which())
|
||||
}
|
||||
reason, err := s.Reason()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Cannot get Reason")
|
||||
}
|
||||
p.Reason = reason
|
||||
return p, nil
|
||||
}
|
@@ -1,455 +0,0 @@
|
||||
package pogs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||
capnp "zombiezen.com/go/capnproto2"
|
||||
)
|
||||
|
||||
// Assert *HTTPOriginConfig implements OriginConfig
|
||||
var _ OriginConfig = (*HTTPOriginConfig)(nil)
|
||||
|
||||
// Assert *WebSocketOriginConfig implements OriginConfig
|
||||
var _ OriginConfig = (*WebSocketOriginConfig)(nil)
|
||||
|
||||
// Assert *HelloWorldOriginConfig implements OriginConfig
|
||||
var _ OriginConfig = (*HelloWorldOriginConfig)(nil)
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
firstVersion := InitVersion()
|
||||
secondVersion := Version(1)
|
||||
assert.False(t, firstVersion.IsNewerOrEqual(secondVersion))
|
||||
assert.True(t, secondVersion.IsNewerOrEqual(firstVersion))
|
||||
assert.True(t, secondVersion.IsNewerOrEqual(secondVersion))
|
||||
}
|
||||
|
||||
func TestClientConfigCapnp(t *testing.T) {
|
||||
for i, testCase := range ClientConfigTestCases() {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewClientConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalClientConfig(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalClientConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func ClientConfigTestCases() []*ClientConfig {
|
||||
|
||||
addDoHProxyConfigs := func(c *ClientConfig) {
|
||||
c.DoHProxyConfigs = []*DoHProxyConfig{
|
||||
sampleDoHProxyConfig(),
|
||||
}
|
||||
}
|
||||
addReverseProxyConfigs := func(c *ClientConfig) {
|
||||
c.ReverseProxyConfigs = []*ReverseProxyConfig{
|
||||
sampleReverseProxyConfig(),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleHTTPOriginConfig()
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleHTTPOriginConfigUnixPath()
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleWebSocketOriginConfig()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
testCases := []*ClientConfig{
|
||||
sampleClientConfig(),
|
||||
sampleClientConfig(addDoHProxyConfigs),
|
||||
sampleClientConfig(addReverseProxyConfigs),
|
||||
sampleClientConfig(addDoHProxyConfigs, addReverseProxyConfigs),
|
||||
}
|
||||
|
||||
return testCases
|
||||
}
|
||||
|
||||
func TestClientConfig(t *testing.T) {
|
||||
for _, testCase := range ClientConfigTestCases() {
|
||||
b, err := testCase.MarshalBytes()
|
||||
assert.NoError(t, err)
|
||||
|
||||
clientConfig, err := UnmarshalClientConfigFromBytes(b)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, testCase, clientConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUseConfigurationResult(t *testing.T) {
|
||||
testCases := []*UseConfigurationResult{
|
||||
&UseConfigurationResult{
|
||||
Success: true,
|
||||
},
|
||||
&UseConfigurationResult{
|
||||
Success: false,
|
||||
FailedConfigs: []*FailedConfig{
|
||||
{
|
||||
Config: sampleReverseProxyConfig(),
|
||||
Reason: "Invalid certificate",
|
||||
},
|
||||
{
|
||||
Config: sampleDoHProxyConfig(),
|
||||
Reason: "Cannot listen on port 53",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewUseConfigurationResult(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalUseConfigurationResult(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalUseConfigurationResult(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoHProxyConfig(t *testing.T) {
|
||||
testCases := []*DoHProxyConfig{
|
||||
sampleDoHProxyConfig(),
|
||||
sampleDoHProxyConfig(func(c *DoHProxyConfig) {
|
||||
c.Upstreams = nil
|
||||
}),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewDoHProxyConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalDoHProxyConfig(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalDoHProxyConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReverseProxyConfig(t *testing.T) {
|
||||
testCases := []*ReverseProxyConfig{
|
||||
sampleReverseProxyConfig(),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleHTTPOriginConfig()
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleHTTPOriginConfigUnixPath()
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.OriginConfig = sampleWebSocketOriginConfig()
|
||||
}),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewReverseProxyConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalReverseProxyConfig(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalReverseProxyConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPOriginConfig(t *testing.T) {
|
||||
testCases := []*HTTPOriginConfig{
|
||||
sampleHTTPOriginConfig(),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewHTTPOriginConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalHTTPOriginConfig(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalHTTPOriginConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWebSocketOriginConfig(t *testing.T) {
|
||||
testCases := []*WebSocketOriginConfig{
|
||||
sampleWebSocketOriginConfig(),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewWebSocketOriginConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalWebSocketOriginConfig(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalWebSocketOriginConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOriginConfigInvalidURL(t *testing.T) {
|
||||
invalidConfigs := []OriginConfig{
|
||||
&HTTPOriginConfig{
|
||||
// this url doesn't have a scheme
|
||||
URLString: "127.0.0.1:36192",
|
||||
},
|
||||
&WebSocketOriginConfig{
|
||||
URLString: "127.0.0.1:36192",
|
||||
},
|
||||
}
|
||||
logger := logger.NewOutputWriter(logger.NewMockWriteManager())
|
||||
|
||||
for _, config := range invalidConfigs {
|
||||
service, err := config.Service(logger)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, service)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Functions to generate sample data for ease of testing
|
||||
//
|
||||
// There's one "sample" function per struct type. Each goes like this:
|
||||
// 1. Initialize an instance of the relevant struct.
|
||||
// 2. Ensure the instance has no zero-valued fields. (This catches the
|
||||
// error-case where a field was added, but we forgot to add code to
|
||||
// marshal/unmarshal this field in CapnProto.)
|
||||
// 3. Apply one or more "override" functions (which accept a
|
||||
// pointer-to-struct, so they can mutate the instance).
|
||||
|
||||
// sampleClientConfig initializes a new ClientConfig literal,
|
||||
// applies any number of overrides to it, and returns it.
|
||||
func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
|
||||
sample := &ClientConfig{
|
||||
Version: Version(1337),
|
||||
SupervisorConfig: sampleSupervisorConfig(),
|
||||
EdgeConnectionConfig: sampleEdgeConnectionConfig(),
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func sampleSupervisorConfig() *SupervisorConfig {
|
||||
sample := &SupervisorConfig{
|
||||
AutoUpdateFrequency: 21 * time.Hour,
|
||||
MetricsUpdateFrequency: 11 * time.Minute,
|
||||
GracePeriod: 31 * time.Second,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
return sample
|
||||
}
|
||||
|
||||
func sampleEdgeConnectionConfig() *EdgeConnectionConfig {
|
||||
sample := &EdgeConnectionConfig{
|
||||
NumHAConnections: 49,
|
||||
HeartbeatInterval: 5 * time.Second,
|
||||
Timeout: 9 * time.Second,
|
||||
MaxFailedHeartbeats: 9001,
|
||||
UserCredentialPath: "/Users/example/.cloudflared/cert.pem",
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
return sample
|
||||
}
|
||||
|
||||
// sampleDoHProxyConfig initializes a new DoHProxyConfig struct,
|
||||
// applies any number of overrides to it, and returns it.
|
||||
func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
|
||||
sample := &DoHProxyConfig{
|
||||
ListenHost: "127.0.0.1",
|
||||
ListenPort: 53,
|
||||
Upstreams: []string{"1.1.1.1", "1.0.0.1"},
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
// sampleReverseProxyConfig initializes a new ReverseProxyConfig struct,
|
||||
// applies any number of overrides to it, and returns it.
|
||||
func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig {
|
||||
sample := &ReverseProxyConfig{
|
||||
TunnelHostname: "mock-non-lb-tunnel.example.com",
|
||||
OriginConfig: &HelloWorldOriginConfig{},
|
||||
Retries: 18,
|
||||
ConnectionTimeout: 5 * time.Second,
|
||||
CompressionQuality: 3,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig {
|
||||
sample := &HTTPOriginConfig{
|
||||
URLString: "https.example.com",
|
||||
TCPKeepAlive: 7 * time.Second,
|
||||
DialDualStack: true,
|
||||
TLSHandshakeTimeout: 11 * time.Second,
|
||||
TLSVerify: true,
|
||||
OriginCAPool: "/etc/cert.pem",
|
||||
OriginServerName: "secure.example.com",
|
||||
MaxIdleConnections: 19,
|
||||
IdleConnectionTimeout: 17 * time.Second,
|
||||
ProxyConnectionTimeout: 15 * time.Second,
|
||||
ExpectContinueTimeout: 21 * time.Second,
|
||||
ChunkedEncoding: true,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func sampleHTTPOriginConfigUnixPath(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig {
|
||||
sample := &HTTPOriginConfig{
|
||||
URLString: "unix:/var/lib/file.sock",
|
||||
TCPKeepAlive: 7 * time.Second,
|
||||
DialDualStack: true,
|
||||
TLSHandshakeTimeout: 11 * time.Second,
|
||||
TLSVerify: true,
|
||||
OriginCAPool: "/etc/cert.pem",
|
||||
OriginServerName: "secure.example.com",
|
||||
MaxIdleConnections: 19,
|
||||
IdleConnectionTimeout: 17 * time.Second,
|
||||
ProxyConnectionTimeout: 15 * time.Second,
|
||||
ExpectContinueTimeout: 21 * time.Second,
|
||||
ChunkedEncoding: true,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *WebSocketOriginConfig {
|
||||
sample := &WebSocketOriginConfig{
|
||||
URLString: "ssh://example.com",
|
||||
TLSVerify: true,
|
||||
OriginCAPool: "/etc/cert.pem",
|
||||
OriginServerName: "secure.example.com",
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func (c *ClientConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{"DoHProxyConfigs", "ReverseProxyConfigs"})
|
||||
}
|
||||
|
||||
func (c *SupervisorConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
func (c *EdgeConnectionConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
func (c *DoHProxyConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
func (c *ReverseProxyConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
func (c *HTTPOriginConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
func (c *WebSocketOriginConfig) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
||||
// ensureNoZeroFieldsInSample checks that all fields in the sample struct,
|
||||
// except those listed in `allowedZeroFieldNames`, are initialized to nonzero
|
||||
// values. Note that the value has to be a pointer for reflection to work
|
||||
// correctly:
|
||||
// e := &ExampleStruct{ ... }
|
||||
// ensureNoZeroFieldsInSample(reflect.ValueOf(e), []string{})
|
||||
//
|
||||
// Context:
|
||||
// Our tests work by taking a sample struct and marshalling/unmarshalling it.
|
||||
// This makes them easy to write, but introduces some risk: if we don't
|
||||
// include a field in the sample value, it won't be covered under tests.
|
||||
// This check reduces that risk by requiring fields to be either initialized
|
||||
// or explicitly uninitialized.
|
||||
func ensureNoZeroFieldsInSample(ptrToSampleValue reflect.Value, allowedZeroFieldNames []string) {
|
||||
sampleValue := ptrToSampleValue.Elem()
|
||||
structType := ptrToSampleValue.Type().Elem()
|
||||
|
||||
allowedZeroFieldSet := make(map[string]bool)
|
||||
for _, name := range allowedZeroFieldNames {
|
||||
if _, ok := structType.FieldByName(name); !ok {
|
||||
panic(fmt.Sprintf("struct %v has no field %v", structType.Name(), name))
|
||||
}
|
||||
allowedZeroFieldSet[name] = true
|
||||
}
|
||||
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
if allowedZeroFieldSet[structType.Field(i).Name] {
|
||||
continue
|
||||
}
|
||||
|
||||
zeroValue := reflect.Zero(structType.Field(i).Type)
|
||||
if reflect.DeepEqual(zeroValue.Interface(), sampleValue.Field(i).Interface()) {
|
||||
panic(fmt.Sprintf("In the sample value for struct %v, field %v was not initialized", structType.Name(), structType.Field(i).Name))
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,11 +3,8 @@ package pogs
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
capnp "zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/pogs"
|
||||
@@ -184,143 +181,6 @@ func UnmarshalRegistrationOptions(s tunnelrpc.RegistrationOptions) (*Registratio
|
||||
return p, err
|
||||
}
|
||||
|
||||
// ConnectResult models the result of Connect RPC, implemented by ConnectError and ConnectSuccess.
|
||||
type ConnectResult interface {
|
||||
ConnectError() *ConnectError
|
||||
ConnectedTo() string
|
||||
ClientConfig() *ClientConfig
|
||||
Marshal(s tunnelrpc.ConnectResult) error
|
||||
}
|
||||
|
||||
func MarshalConnectResult(s tunnelrpc.ConnectResult, p ConnectResult) error {
|
||||
return p.Marshal(s)
|
||||
}
|
||||
|
||||
func UnmarshalConnectResult(s tunnelrpc.ConnectResult) (ConnectResult, error) {
|
||||
switch s.Result().Which() {
|
||||
case tunnelrpc.ConnectResult_result_Which_err:
|
||||
capnpConnectError, err := s.Result().Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return UnmarshalConnectError(capnpConnectError)
|
||||
case tunnelrpc.ConnectResult_result_Which_success:
|
||||
capnpConnectSuccess, err := s.Result().Success()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return UnmarshalConnectSuccess(capnpConnectSuccess)
|
||||
default:
|
||||
return nil, fmt.Errorf("Unmarshal %v not implemented yet", s.Result().Which().String())
|
||||
}
|
||||
}
|
||||
|
||||
// ConnectSuccess is the concrete returned type when Connect RPC succeed
|
||||
type ConnectSuccess struct {
|
||||
ServerLocationName string
|
||||
Config *ClientConfig
|
||||
}
|
||||
|
||||
func (*ConnectSuccess) ConnectError() *ConnectError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs *ConnectSuccess) ConnectedTo() string {
|
||||
return cs.ServerLocationName
|
||||
}
|
||||
|
||||
func (cs *ConnectSuccess) ClientConfig() *ClientConfig {
|
||||
return cs.Config
|
||||
}
|
||||
|
||||
func (cs *ConnectSuccess) Marshal(s tunnelrpc.ConnectResult) error {
|
||||
capnpConnectSuccess, err := s.Result().NewSuccess()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = capnpConnectSuccess.SetServerLocationName(cs.ServerLocationName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to set ConnectSuccess.ServerLocationName")
|
||||
}
|
||||
|
||||
if cs.Config != nil {
|
||||
capnpClientConfig, err := capnpConnectSuccess.NewClientConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to initialize ConnectSuccess.ClientConfig")
|
||||
}
|
||||
if err := MarshalClientConfig(capnpClientConfig, cs.Config); err != nil {
|
||||
return errors.Wrap(err, "failed to marshal ClientConfig")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalConnectSuccess(s tunnelrpc.ConnectSuccess) (*ConnectSuccess, error) {
|
||||
p := new(ConnectSuccess)
|
||||
|
||||
serverLocationName, err := s.ServerLocationName()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get tunnelrpc.ConnectSuccess.ServerLocationName")
|
||||
}
|
||||
p.ServerLocationName = serverLocationName
|
||||
|
||||
if s.HasClientConfig() {
|
||||
capnpClientConfig, err := s.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get tunnelrpc.ConnectSuccess.ClientConfig")
|
||||
}
|
||||
p.Config, err = UnmarshalClientConfig(capnpClientConfig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get unmarshal ClientConfig")
|
||||
}
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ConnectError is the concrete returned type when Connect RPC encounters some error
|
||||
type ConnectError struct {
|
||||
Cause string
|
||||
RetryAfter time.Duration
|
||||
ShouldRetry bool
|
||||
}
|
||||
|
||||
func (ce *ConnectError) ConnectError() *ConnectError {
|
||||
return ce
|
||||
}
|
||||
|
||||
func (*ConnectError) ConnectedTo() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (*ConnectError) ClientConfig() *ClientConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ce *ConnectError) Marshal(s tunnelrpc.ConnectResult) error {
|
||||
capnpConnectError, err := s.Result().NewErr()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return MarshalConnectError(capnpConnectError, ce)
|
||||
}
|
||||
|
||||
func MarshalConnectError(s tunnelrpc.ConnectError, p *ConnectError) error {
|
||||
return pogs.Insert(tunnelrpc.ConnectError_TypeID, s.Struct, p)
|
||||
}
|
||||
|
||||
func UnmarshalConnectError(s tunnelrpc.ConnectError) (*ConnectError, error) {
|
||||
p := new(ConnectError)
|
||||
err := pogs.Extract(p, tunnelrpc.ConnectError_TypeID, s.Struct)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (e *ConnectError) Error() string {
|
||||
return e.Cause
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
@@ -340,102 +200,10 @@ func UnmarshalServerInfo(s tunnelrpc.ServerInfo) (*ServerInfo, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
type ConnectParameters struct {
|
||||
OriginCert []byte
|
||||
CloudflaredID uuid.UUID
|
||||
NumPreviousAttempts uint8
|
||||
Tags []Tag
|
||||
CloudflaredVersion string
|
||||
IntentLabel string
|
||||
}
|
||||
|
||||
func MarshalConnectParameters(s tunnelrpc.CapnpConnectParameters, p *ConnectParameters) error {
|
||||
if err := s.SetOriginCert(p.OriginCert); err != nil {
|
||||
return err
|
||||
}
|
||||
cloudflaredIDBytes, err := p.CloudflaredID.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.SetCloudflaredID(cloudflaredIDBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
s.SetNumPreviousAttempts(p.NumPreviousAttempts)
|
||||
if len(p.Tags) > 0 {
|
||||
tagsCapnpList, err := s.NewTags(int32(len(p.Tags)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, tag := range p.Tags {
|
||||
tagCapnp := tagsCapnpList.At(i)
|
||||
if err := tagCapnp.SetName(tag.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tagCapnp.SetValue(tag.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := s.SetCloudflaredVersion(p.CloudflaredVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.SetIntentLabel(p.IntentLabel)
|
||||
}
|
||||
|
||||
func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectParameters, error) {
|
||||
originCert, err := s.OriginCert()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cloudflaredIDBytes, err := s.CloudflaredID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cloudflaredID, err := uuid.FromBytes(cloudflaredIDBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tagsCapnpList, err := s.Tags()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tags []Tag
|
||||
for i := 0; i < tagsCapnpList.Len(); i++ {
|
||||
tagCapnp := tagsCapnpList.At(i)
|
||||
name, err := tagCapnp.Name()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value, err := tagCapnp.Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tags = append(tags, Tag{Name: name, Value: value})
|
||||
}
|
||||
|
||||
cloudflaredVersion, err := s.CloudflaredVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
intentLabel, err := s.IntentLabel()
|
||||
return &ConnectParameters{
|
||||
OriginCert: originCert,
|
||||
CloudflaredID: cloudflaredID,
|
||||
NumPreviousAttempts: s.NumPreviousAttempts(),
|
||||
Tags: tags,
|
||||
CloudflaredVersion: cloudflaredVersion,
|
||||
IntentLabel: intentLabel,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type TunnelServer interface {
|
||||
RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration
|
||||
GetServerInfo(ctx context.Context) (*ServerInfo, error)
|
||||
UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error
|
||||
Connect(ctx context.Context, parameters *ConnectParameters) (ConnectResult, error)
|
||||
Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error)
|
||||
ReconnectTunnel(ctx context.Context, jwt, eventDigest, connDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error)
|
||||
}
|
||||
@@ -494,25 +262,8 @@ func (i TunnelServer_PogsImpl) UnregisterTunnel(p tunnelrpc.TunnelServer_unregis
|
||||
return i.impl.UnregisterTunnel(p.Ctx, gracePeriodNanoSec)
|
||||
}
|
||||
|
||||
func (i TunnelServer_PogsImpl) Connect(p tunnelrpc.TunnelServer_connect) error {
|
||||
parameters, err := p.Params.Parameters()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pogsParameters, err := UnmarshalConnectParameters(parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
server.Ack(p.Options)
|
||||
connectResult, err := i.impl.Connect(p.Ctx, pogsParameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := p.Results.NewResult()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return connectResult.Marshal(result)
|
||||
func (i TunnelServer_PogsImpl) ObsoleteDeclarativeTunnelConnect(p tunnelrpc.TunnelServer_obsoleteDeclarativeTunnelConnect) error {
|
||||
return fmt.Errorf("RPC to create declarative tunnel connection has been deprecated")
|
||||
}
|
||||
|
||||
type TunnelServer_PogsClient struct {
|
||||
@@ -578,25 +329,3 @@ func (c TunnelServer_PogsClient) UnregisterTunnel(ctx context.Context, gracePeri
|
||||
_, err := promise.Struct()
|
||||
return err
|
||||
}
|
||||
|
||||
func (c TunnelServer_PogsClient) Connect(ctx context.Context,
|
||||
parameters *ConnectParameters,
|
||||
) (ConnectResult, error) {
|
||||
client := tunnelrpc.TunnelServer{Client: c.Client}
|
||||
promise := client.Connect(ctx, func(p tunnelrpc.TunnelServer_connect_Params) error {
|
||||
connectParameters, err := p.NewParameters()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = MarshalConnectParameters(connectParameters, parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
retval, err := promise.Result().Struct()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return UnmarshalConnectResult(retval)
|
||||
}
|
||||
|
@@ -2,12 +2,9 @@ package pogs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
capnp "zombiezen.com/go/capnproto2"
|
||||
)
|
||||
@@ -56,94 +53,3 @@ func TestTunnelRegistration(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestConnectResult(t *testing.T) {
|
||||
testCases := []ConnectResult{
|
||||
&ConnectError{
|
||||
Cause: "it broke",
|
||||
ShouldRetry: false,
|
||||
RetryAfter: 2 * time.Second,
|
||||
},
|
||||
&ConnectSuccess{
|
||||
ServerLocationName: "SFO",
|
||||
Config: sampleClientConfig(),
|
||||
},
|
||||
&ConnectSuccess{
|
||||
ServerLocationName: "",
|
||||
Config: nil,
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewConnectResult(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalConnectResult(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase #%v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalConnectResult(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase #%v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectParameters(t *testing.T) {
|
||||
testCases := []*ConnectParameters{
|
||||
sampleConnectParameters(),
|
||||
sampleConnectParameters(func(c *ConnectParameters) {
|
||||
c.IntentLabel = "my_intent"
|
||||
}),
|
||||
sampleConnectParameters(func(c *ConnectParameters) {
|
||||
c.Tags = nil
|
||||
}),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewCapnpConnectParameters(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal("Couldn't initialize a new message")
|
||||
}
|
||||
err = MarshalConnectParameters(capnpEntity, testCase)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalConnectParameters(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
||||
}
|
||||
}
|
||||
|
||||
func sampleConnectParameters(overrides ...func(*ConnectParameters)) *ConnectParameters {
|
||||
cloudflaredID, err := uuid.Parse("ED7BA470-8E54-465E-825C-99712043E01C")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sample := &ConnectParameters{
|
||||
OriginCert: []byte("my-origin-cert"),
|
||||
CloudflaredID: cloudflaredID,
|
||||
NumPreviousAttempts: 19,
|
||||
Tags: []Tag{
|
||||
Tag{
|
||||
Name: "provision-method",
|
||||
Value: "new",
|
||||
},
|
||||
},
|
||||
CloudflaredVersion: "7.0",
|
||||
IntentLabel: "my_intent",
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
return sample
|
||||
}
|
||||
|
||||
func (c *ConnectParameters) ensureNoZeroFields() {
|
||||
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
|
||||
}
|
||||
|
@@ -295,7 +295,8 @@ interface TunnelServer {
|
||||
registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
||||
getServerInfo @1 () -> (result :ServerInfo);
|
||||
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
|
||||
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
|
||||
# obsoleteDeclarativeTunnelConnect RPC deprecated in TUN-3019
|
||||
obsoleteDeclarativeTunnelConnect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
|
||||
authenticate @4 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :AuthenticateResponse);
|
||||
reconnectTunnel @5 (jwt :Data, eventDigest :Data, connDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
||||
}
|
||||
|
@@ -2874,9 +2874,9 @@ func (c TunnelServer) UnregisterTunnel(ctx context.Context, params func(TunnelSe
|
||||
}
|
||||
return TunnelServer_unregisterTunnel_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}
|
||||
}
|
||||
func (c TunnelServer) Connect(ctx context.Context, params func(TunnelServer_connect_Params) error, opts ...capnp.CallOption) TunnelServer_connect_Results_Promise {
|
||||
func (c TunnelServer) ObsoleteDeclarativeTunnelConnect(ctx context.Context, params func(TunnelServer_obsoleteDeclarativeTunnelConnect_Params) error, opts ...capnp.CallOption) TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise {
|
||||
if c.Client == nil {
|
||||
return TunnelServer_connect_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}
|
||||
}
|
||||
call := &capnp.Call{
|
||||
Ctx: ctx,
|
||||
@@ -2884,15 +2884,17 @@ func (c TunnelServer) Connect(ctx context.Context, params func(TunnelServer_conn
|
||||
InterfaceID: 0xea58385c65416035,
|
||||
MethodID: 3,
|
||||
InterfaceName: "tunnelrpc/tunnelrpc.capnp:TunnelServer",
|
||||
MethodName: "connect",
|
||||
MethodName: "obsoleteDeclarativeTunnelConnect",
|
||||
},
|
||||
Options: capnp.NewCallOptions(opts),
|
||||
}
|
||||
if params != nil {
|
||||
call.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 1}
|
||||
call.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_connect_Params{Struct: s}) }
|
||||
call.ParamsFunc = func(s capnp.Struct) error {
|
||||
return params(TunnelServer_obsoleteDeclarativeTunnelConnect_Params{Struct: s})
|
||||
}
|
||||
}
|
||||
return TunnelServer_connect_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}
|
||||
}
|
||||
func (c TunnelServer) Authenticate(ctx context.Context, params func(TunnelServer_authenticate_Params) error, opts ...capnp.CallOption) TunnelServer_authenticate_Results_Promise {
|
||||
if c.Client == nil {
|
||||
@@ -2942,7 +2944,7 @@ type TunnelServer_Server interface {
|
||||
|
||||
UnregisterTunnel(TunnelServer_unregisterTunnel) error
|
||||
|
||||
Connect(TunnelServer_connect) error
|
||||
ObsoleteDeclarativeTunnelConnect(TunnelServer_obsoleteDeclarativeTunnelConnect) error
|
||||
|
||||
Authenticate(TunnelServer_authenticate) error
|
||||
|
||||
@@ -3006,11 +3008,11 @@ func TunnelServer_Methods(methods []server.Method, s TunnelServer_Server) []serv
|
||||
InterfaceID: 0xea58385c65416035,
|
||||
MethodID: 3,
|
||||
InterfaceName: "tunnelrpc/tunnelrpc.capnp:TunnelServer",
|
||||
MethodName: "connect",
|
||||
MethodName: "obsoleteDeclarativeTunnelConnect",
|
||||
},
|
||||
Impl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {
|
||||
call := TunnelServer_connect{c, opts, TunnelServer_connect_Params{Struct: p}, TunnelServer_connect_Results{Struct: r}}
|
||||
return s.Connect(call)
|
||||
call := TunnelServer_obsoleteDeclarativeTunnelConnect{c, opts, TunnelServer_obsoleteDeclarativeTunnelConnect_Params{Struct: p}, TunnelServer_obsoleteDeclarativeTunnelConnect_Results{Struct: r}}
|
||||
return s.ObsoleteDeclarativeTunnelConnect(call)
|
||||
},
|
||||
ResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},
|
||||
})
|
||||
@@ -3070,12 +3072,12 @@ type TunnelServer_unregisterTunnel struct {
|
||||
Results TunnelServer_unregisterTunnel_Results
|
||||
}
|
||||
|
||||
// TunnelServer_connect holds the arguments for a server call to TunnelServer.connect.
|
||||
type TunnelServer_connect struct {
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect holds the arguments for a server call to TunnelServer.obsoleteDeclarativeTunnelConnect.
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect struct {
|
||||
Ctx context.Context
|
||||
Options capnp.CallOptions
|
||||
Params TunnelServer_connect_Params
|
||||
Results TunnelServer_connect_Results
|
||||
Params TunnelServer_obsoleteDeclarativeTunnelConnect_Params
|
||||
Results TunnelServer_obsoleteDeclarativeTunnelConnect_Results
|
||||
}
|
||||
|
||||
// TunnelServer_authenticate holds the arguments for a server call to TunnelServer.authenticate.
|
||||
@@ -3552,48 +3554,48 @@ func (p TunnelServer_unregisterTunnel_Results_Promise) Struct() (TunnelServer_un
|
||||
return TunnelServer_unregisterTunnel_Results{s}, err
|
||||
}
|
||||
|
||||
type TunnelServer_connect_Params struct{ capnp.Struct }
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Params struct{ capnp.Struct }
|
||||
|
||||
// TunnelServer_connect_Params_TypeID is the unique identifier for the type TunnelServer_connect_Params.
|
||||
const TunnelServer_connect_Params_TypeID = 0xa766b24d4fe5da35
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_TypeID is the unique identifier for the type TunnelServer_obsoleteDeclarativeTunnelConnect_Params.
|
||||
const TunnelServer_obsoleteDeclarativeTunnelConnect_Params_TypeID = 0xa766b24d4fe5da35
|
||||
|
||||
func NewTunnelServer_connect_Params(s *capnp.Segment) (TunnelServer_connect_Params, error) {
|
||||
func NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {
|
||||
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
|
||||
return TunnelServer_connect_Params{st}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params{st}, err
|
||||
}
|
||||
|
||||
func NewRootTunnelServer_connect_Params(s *capnp.Segment) (TunnelServer_connect_Params, error) {
|
||||
func NewRootTunnelServer_obsoleteDeclarativeTunnelConnect_Params(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {
|
||||
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
|
||||
return TunnelServer_connect_Params{st}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params{st}, err
|
||||
}
|
||||
|
||||
func ReadRootTunnelServer_connect_Params(msg *capnp.Message) (TunnelServer_connect_Params, error) {
|
||||
func ReadRootTunnelServer_obsoleteDeclarativeTunnelConnect_Params(msg *capnp.Message) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {
|
||||
root, err := msg.RootPtr()
|
||||
return TunnelServer_connect_Params{root.Struct()}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params{root.Struct()}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params) String() string {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) String() string {
|
||||
str, _ := text.Marshal(0xa766b24d4fe5da35, s.Struct)
|
||||
return str
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params) Parameters() (CapnpConnectParameters, error) {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) Parameters() (CapnpConnectParameters, error) {
|
||||
p, err := s.Struct.Ptr(0)
|
||||
return CapnpConnectParameters{Struct: p.Struct()}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params) HasParameters() bool {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) HasParameters() bool {
|
||||
p, err := s.Struct.Ptr(0)
|
||||
return p.IsValid() || err != nil
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params) SetParameters(v CapnpConnectParameters) error {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) SetParameters(v CapnpConnectParameters) error {
|
||||
return s.Struct.SetPtr(0, v.Struct.ToPtr())
|
||||
}
|
||||
|
||||
// NewParameters sets the parameters field to a newly
|
||||
// allocated CapnpConnectParameters struct, preferring placement in s's segment.
|
||||
func (s TunnelServer_connect_Params) NewParameters() (CapnpConnectParameters, error) {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) NewParameters() (CapnpConnectParameters, error) {
|
||||
ss, err := NewCapnpConnectParameters(s.Struct.Segment())
|
||||
if err != nil {
|
||||
return CapnpConnectParameters{}, err
|
||||
@@ -3602,82 +3604,82 @@ func (s TunnelServer_connect_Params) NewParameters() (CapnpConnectParameters, er
|
||||
return ss, err
|
||||
}
|
||||
|
||||
// TunnelServer_connect_Params_List is a list of TunnelServer_connect_Params.
|
||||
type TunnelServer_connect_Params_List struct{ capnp.List }
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List is a list of TunnelServer_obsoleteDeclarativeTunnelConnect_Params.
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List struct{ capnp.List }
|
||||
|
||||
// NewTunnelServer_connect_Params creates a new list of TunnelServer_connect_Params.
|
||||
func NewTunnelServer_connect_Params_List(s *capnp.Segment, sz int32) (TunnelServer_connect_Params_List, error) {
|
||||
// NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params creates a new list of TunnelServer_obsoleteDeclarativeTunnelConnect_Params.
|
||||
func NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params_List(s *capnp.Segment, sz int32) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List, error) {
|
||||
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)
|
||||
return TunnelServer_connect_Params_List{l}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List{l}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params_List) At(i int) TunnelServer_connect_Params {
|
||||
return TunnelServer_connect_Params{s.List.Struct(i)}
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) At(i int) TunnelServer_obsoleteDeclarativeTunnelConnect_Params {
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params{s.List.Struct(i)}
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params_List) Set(i int, v TunnelServer_connect_Params) error {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) Set(i int, v TunnelServer_obsoleteDeclarativeTunnelConnect_Params) error {
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Params_List) String() string {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) String() string {
|
||||
str, _ := text.MarshalList(0xa766b24d4fe5da35, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_connect_Params_Promise is a wrapper for a TunnelServer_connect_Params promised by a client call.
|
||||
type TunnelServer_connect_Params_Promise struct{ *capnp.Pipeline }
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise is a wrapper for a TunnelServer_obsoleteDeclarativeTunnelConnect_Params promised by a client call.
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
func (p TunnelServer_connect_Params_Promise) Struct() (TunnelServer_connect_Params, error) {
|
||||
func (p TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise) Struct() (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {
|
||||
s, err := p.Pipeline.Struct()
|
||||
return TunnelServer_connect_Params{s}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Params{s}, err
|
||||
}
|
||||
|
||||
func (p TunnelServer_connect_Params_Promise) Parameters() CapnpConnectParameters_Promise {
|
||||
func (p TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise) Parameters() CapnpConnectParameters_Promise {
|
||||
return CapnpConnectParameters_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
|
||||
}
|
||||
|
||||
type TunnelServer_connect_Results struct{ capnp.Struct }
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Results struct{ capnp.Struct }
|
||||
|
||||
// TunnelServer_connect_Results_TypeID is the unique identifier for the type TunnelServer_connect_Results.
|
||||
const TunnelServer_connect_Results_TypeID = 0xfeac5c8f4899ef7c
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_TypeID is the unique identifier for the type TunnelServer_obsoleteDeclarativeTunnelConnect_Results.
|
||||
const TunnelServer_obsoleteDeclarativeTunnelConnect_Results_TypeID = 0xfeac5c8f4899ef7c
|
||||
|
||||
func NewTunnelServer_connect_Results(s *capnp.Segment) (TunnelServer_connect_Results, error) {
|
||||
func NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {
|
||||
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
|
||||
return TunnelServer_connect_Results{st}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results{st}, err
|
||||
}
|
||||
|
||||
func NewRootTunnelServer_connect_Results(s *capnp.Segment) (TunnelServer_connect_Results, error) {
|
||||
func NewRootTunnelServer_obsoleteDeclarativeTunnelConnect_Results(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {
|
||||
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
|
||||
return TunnelServer_connect_Results{st}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results{st}, err
|
||||
}
|
||||
|
||||
func ReadRootTunnelServer_connect_Results(msg *capnp.Message) (TunnelServer_connect_Results, error) {
|
||||
func ReadRootTunnelServer_obsoleteDeclarativeTunnelConnect_Results(msg *capnp.Message) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {
|
||||
root, err := msg.RootPtr()
|
||||
return TunnelServer_connect_Results{root.Struct()}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results{root.Struct()}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results) String() string {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) String() string {
|
||||
str, _ := text.Marshal(0xfeac5c8f4899ef7c, s.Struct)
|
||||
return str
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results) Result() (ConnectResult, error) {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) Result() (ConnectResult, error) {
|
||||
p, err := s.Struct.Ptr(0)
|
||||
return ConnectResult{Struct: p.Struct()}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results) HasResult() bool {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) HasResult() bool {
|
||||
p, err := s.Struct.Ptr(0)
|
||||
return p.IsValid() || err != nil
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results) SetResult(v ConnectResult) error {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) SetResult(v ConnectResult) error {
|
||||
return s.Struct.SetPtr(0, v.Struct.ToPtr())
|
||||
}
|
||||
|
||||
// NewResult sets the result field to a newly
|
||||
// allocated ConnectResult struct, preferring placement in s's segment.
|
||||
func (s TunnelServer_connect_Results) NewResult() (ConnectResult, error) {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) NewResult() (ConnectResult, error) {
|
||||
ss, err := NewConnectResult(s.Struct.Segment())
|
||||
if err != nil {
|
||||
return ConnectResult{}, err
|
||||
@@ -3686,37 +3688,37 @@ func (s TunnelServer_connect_Results) NewResult() (ConnectResult, error) {
|
||||
return ss, err
|
||||
}
|
||||
|
||||
// TunnelServer_connect_Results_List is a list of TunnelServer_connect_Results.
|
||||
type TunnelServer_connect_Results_List struct{ capnp.List }
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List is a list of TunnelServer_obsoleteDeclarativeTunnelConnect_Results.
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List struct{ capnp.List }
|
||||
|
||||
// NewTunnelServer_connect_Results creates a new list of TunnelServer_connect_Results.
|
||||
func NewTunnelServer_connect_Results_List(s *capnp.Segment, sz int32) (TunnelServer_connect_Results_List, error) {
|
||||
// NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results creates a new list of TunnelServer_obsoleteDeclarativeTunnelConnect_Results.
|
||||
func NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results_List(s *capnp.Segment, sz int32) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List, error) {
|
||||
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)
|
||||
return TunnelServer_connect_Results_List{l}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List{l}, err
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results_List) At(i int) TunnelServer_connect_Results {
|
||||
return TunnelServer_connect_Results{s.List.Struct(i)}
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) At(i int) TunnelServer_obsoleteDeclarativeTunnelConnect_Results {
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results{s.List.Struct(i)}
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results_List) Set(i int, v TunnelServer_connect_Results) error {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) Set(i int, v TunnelServer_obsoleteDeclarativeTunnelConnect_Results) error {
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_connect_Results_List) String() string {
|
||||
func (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) String() string {
|
||||
str, _ := text.MarshalList(0xfeac5c8f4899ef7c, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_connect_Results_Promise is a wrapper for a TunnelServer_connect_Results promised by a client call.
|
||||
type TunnelServer_connect_Results_Promise struct{ *capnp.Pipeline }
|
||||
// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise is a wrapper for a TunnelServer_obsoleteDeclarativeTunnelConnect_Results promised by a client call.
|
||||
type TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
func (p TunnelServer_connect_Results_Promise) Struct() (TunnelServer_connect_Results, error) {
|
||||
func (p TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise) Struct() (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {
|
||||
s, err := p.Pipeline.Struct()
|
||||
return TunnelServer_connect_Results{s}, err
|
||||
return TunnelServer_obsoleteDeclarativeTunnelConnect_Results{s}, err
|
||||
}
|
||||
|
||||
func (p TunnelServer_connect_Results_Promise) Result() ConnectResult_Promise {
|
||||
func (p TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise) Result() ConnectResult_Promise {
|
||||
return ConnectResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
|
||||
}
|
||||
|
||||
@@ -4383,257 +4385,259 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio
|
||||
return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
|
||||
}
|
||||
|
||||
const schema_db8274f9144abc7e = "x\xda\xccz}\x90\x14uz\xff\xf3t\xcf\xd2\xbb\xb0" +
|
||||
"\xcbL\xdbc\xfdv)\xf67\xc7\x8bQ8!\"G" +
|
||||
"\xa2\x9b\xe4\xf6\x0d\xb8]\x0ea{g\x17u\xe5R\xf6" +
|
||||
"\xce|w\xb6a\xa6{\xe8\xee\x01\x96\xe0\xf1R\x10e" +
|
||||
"\x03'x\x90\x02\x0f\xaf\x00\x8f\xf8\x12\xbd\x13\x0f+\xa7" +
|
||||
"\x11K\x93\xab\xa89\x13\xe5\x82)\xbd\x98\x8a\x11\xa8T" +
|
||||
"\xac\xb3<\xd1\x94eJ\xed\xd4\xf3\xed\xd7\x1d\x96\x05L" +
|
||||
"R\x95\x7f`\xea\xe9\xe7\xfb\xf2\xbc}\x9e\x97\xef\xde\xf4" +
|
||||
"\xe3\xc9m\xc2\x82\x9a\xeb\x93\x00\xeaS5\x93\\6\xf7" +
|
||||
"\x97\x9b\x8e\\\xf7\xd7\xdbA\x9d\x86\xe8~\xf7\xf9e\xe9" +
|
||||
"\xcf\x9c\xed\xff\x045\xa2\x04\xb0pD\xda\x84\xca\x1eI" +
|
||||
"\x02PvI\xff\x06\xe8\xd6\xfc\xd6\x9b\xef\x96\xdf\x95v" +
|
||||
"\x80<-\xce,\x10s\xa9v\x19*\xdbj\x89\xf9\x9e" +
|
||||
"\xda\x0d\x80\xee\xef\x97^?\xf6;\x07~A\xccB\xc4" +
|
||||
"\x0c\xb8\xf0|\xed&T>\xe3\x9c\xffQ\xbb\x12\xd0\xfd" +
|
||||
"x\x7f\xe3\x9f\x1f\xfd\xfbWv\x82|=\x82\x7fvC" +
|
||||
"\xdd\xaf\x10P\x99Q\xf7\x13@\xf7\x1fn\xda|\xee\xee" +
|
||||
"\x8f\xf7\xdd7\xf6\xdc\x04\xf1\xbdT7\x8a\xca\xdbu\x12" +
|
||||
"\x88\xeeCw\xa5\xff\x16\x8f|\xba\x0f\xe4\x1bh\x1b\xa4" +
|
||||
"\xcf\xcf\xd4M\x16\x00\x95\xbf\xabk\x05t_\xbf\xf1\xf9" +
|
||||
"\xe7\xf6\xfe\xf4\xde\x1f\x80z=\"x\xeb?\xa8\xfbO" +
|
||||
":\x07'\x13\xc3G?\xfaz\xe2\xc9\xd7\xaf\xf9!g" +
|
||||
"p\x8f\x9f\xbe\xfd\xe9\xbd?\xfd\xda\xfb\xd0/H\x98\x00" +
|
||||
"X8g\xb2E\xbc\x8b&\x93.\xf6\xbfujEi" +
|
||||
"\xdf\x83\xc7\xbcK\xf3\xbd\xae\x9d\"\x08\x90pwt\x7f" +
|
||||
"Z\xea\x7f8\xfb\xb0/N\x0d}\xaa\x9br\x01\x01\x17" +
|
||||
"6O\xc9 \xa0\xbb\xe8W\xe7W\xde\xf6\xf4\xd0#>" +
|
||||
"\x07\xbf\xe9\xad\xf5O\xd3\xe6\xdd\xf5t\x91W6\xa4v" +
|
||||
"\xb7\xff\xee\xfd\x8fT\x9b\x85\xefU\xaa\x1fEeg=" +
|
||||
"\xfd\xdcV\x7f;\xed7z\xeb\xa9U\x1f\xff\xb1\xfd8" +
|
||||
"\xa8\xf30\xe1\xfe|\xd7\xd9\xf5s\x1e\x1bz\x99\xdf[" +
|
||||
"\x04X\xf8Y\xc3/i\xeb\x86\xa9\xa4\xcb\x86\xbf\x9c\xbb" +
|
||||
"\xe2\xfes\xcbO\xd0\xd61\xbbx\x97xrj\x0b*" +
|
||||
"\xa7\xa6\x92i\x9e\xe5\xdco\xdc\xb8\xea\x85\x17\x9e*\x9c" +
|
||||
"\xa8\xbe\x087\xf9\x9d\xc9e\xa8\x94\x92\xc4\xad'\x89\xfb" +
|
||||
"\xdan|\xe7\xc5\x05\x89\xbf\x88\x1b\xb29\xf5>\x1d\xbe" +
|
||||
" E\x0cw}\xfe\xcc_-\xf9\xf0\xcc\xb3q\x13\x9d" +
|
||||
"N\x09d\xa2\xf3)\x12|`\x14K\xef\xb4\xb4\xbd\x00" +
|
||||
"\xea\x0d\x88\xee\x9a\x03\x9b\x9d\xae\x83{\\\xe8G\x09\x05" +
|
||||
"\xf2\x0ay\x13m\xd6$\x93\x835\x7f\xd0\xd1`|\xb8" +
|
||||
"\xfd\xc5*o\xe4\xa7V\xe4e\xa8\xec\x92\xe9j;\xe5" +
|
||||
"\x9f\x00~\xfa\xf8\xbd{\xbb\xcf.~Y\x9d\x86\x89j" +
|
||||
"\xa1g\\\xb3\x09\x95E\xd7\xd0\xcf\x05\xd7p\xfb\x84\x1a" +
|
||||
"\xacb\xe7Rk\xca\x1aT*\x0a\xfd\\\xa7p\xf6e" +
|
||||
"w}\xff\x81\x9a\xf3\xdf\x7f\xb9Z\xa5\xe4\xe2\x0b\xefI" +
|
||||
"[\xa8\xecK\xd3\xcf=\xe9\xff'\x02\xba\xd3\x9e\xfa\xbd" +
|
||||
"\x1fw\xe4\xdf\xfe\xc58Q\xa444^P\x9a\x1a\xe9" +
|
||||
"\xd7\xb5\x8d$\xe3\xd9y'\xfe\xe8\xdf\xf7\x9c>\x13\xf7" +
|
||||
"\x94u\x8d\xdcew6\x92\xc2\xee\xfd\xfa\xc8\xa6\x15\xd7" +
|
||||
"\x8d\xbeYm \xcey\xbcq\x14\x95S|\xbbg\xf9" +
|
||||
"v\xc2y\xadi\xeb?~\xf3\x9d\x98\xd3\xceiz\x0f" +
|
||||
"!\xe1\xaeXu\xd7\x9a\xba{\xce\x9e\x8d\x1f\xd4\xdc\xe4" +
|
||||
"\x99\xae\x89\x0e:)?\xa0<\x7f\xf4\xcf\xce\xd1AR" +
|
||||
"\xb5\xba\xd5\xa6\x01TX\x13WO\xd3#\x02\xc4\x82g" +
|
||||
"<\xc7\xf9\xce\xf4\x16TJ\xd3\xb9\xe3L\xa7{-\xba" +
|
||||
"\xbb\x9d\xad\xbe\xe5\x8e\xf7A\x9e&\x8e\xc1\x8a\xc7\x88\xf3" +
|
||||
"\xd9\xe9<\x94\xa7\xdf\x8b\xca\xa9f\x09\xc0\xfd^a\xe0" +
|
||||
"\xd5\x8f:\x8f\xfe\xa6zs.\xd0\xf1\xe6\x16T\x9e!" +
|
||||
"\xbe\x85'\x9a\xb9}\x16.\xf8\x93\x0f\x0e<\xdc\xf9\xd1" +
|
||||
"E\xbb\x7f\xf1\xff;Pi\xc8\xd0=\xea2\xdfRn" +
|
||||
"\xcd\xf0\xcd\xbf\xbbx\xe5\xad3_\xba\x10\xd7\xc4\x8c\xcc" +
|
||||
"\x05\x1e\xf9\x19\xd2\xc4\xd0-\xbf\xfe\xd6u\xdf\xfb\x9b\x0b" +
|
||||
"U\xf6\xe3\x8c\xfd\x99\xb9\xa80\xbe\xa3F\xcc\x1f.\xfd" +
|
||||
"\xe1\x99i\xc9i\x9fT]t\x12\xf1\xee\xcc\xacA\xe5" +
|
||||
"\x10\xf1.<\x90y\x99.z\xc7{\x0fnh\xfd\xc1" +
|
||||
"'\x9f\x92\\b\x15\xd0\xed\x9a1\x80\xcaC3h\xe7" +
|
||||
"C3(\x96\x96?\xf1\xf67\x87\x0f\xbc\xf2\xd9\xb8\xd0" +
|
||||
"\xbdd\xe6vT\xee\x9cI\xdc\xfd3\x09\xae\xfeT:" +
|
||||
"|v\xeb\xbf\xfc\xe1\xe7q\xa9\xfe`\xd6{$\x95:" +
|
||||
"\x8b\xa4\xda\xfc\xe1\xa1\xae\xfbW?\xf1\xe5\x18O\x9b\xf5" +
|
||||
"\x1c1l\xe3\x0ca0\x8e\xe7iGgu\xa0rb" +
|
||||
"\x16\x9d\xf7\xe4\xacV\x98\xe7:\x15\xc3`E\xab\x9c\xc8" +
|
||||
"\xfdv\xf037?\xa7\x95\x8drK{\xc5\x19f\x86" +
|
||||
"\xa3\xe74\x87\xf5\xb2V\xbbl\x1a6\xebATSb" +
|
||||
"\x02 \x81\x00\xb2\xb6\x06@\xbd[D\xb5(\xa0\x8c\x98" +
|
||||
"&\xb8\x96u\"\x0e\x8b\xa8:\x02\xca\x82\x90&D\x90" +
|
||||
"\xd7\xcd\x04P\x8b\"\xaa\x1b\x05D1Mx'W\x1e" +
|
||||
"\x00P7\x8a\xa8\xee\x10\xd0-3\xab\xa4\x19\xcc\x80\xa4" +
|
||||
"\xb3\xc4\xb2\xb0\x1e\x04\xac\x07t-\xe6X#\xda`\x11" +
|
||||
"\x92,F\x96\xd6lp\xb0\x01\x04l\x00t\x87\xcd\x8a" +
|
||||
"e\xf7\x1b\x0e\xea\xc5^6d1\x1b\x87q\x12\x088" +
|
||||
"\x09p\"\xf1:M\xc3`9'[\xc9\xe5\x98m\x03" +
|
||||
"\x90d\xb5\xa1ds\x1e\x04Po\x14Q\xbd%&\xd9" +
|
||||
"\"\x92\xec\x1b\"\xaam\x02\xba6\xb3\xd63k\xb9\x89" +
|
||||
"9\xcd\xd1Mc\x85&\x96Xx\xed\\Qg\x86\xd3" +
|
||||
"iB\xd2\x18\xd2\x0b\x98\x8aB\x01\x10S\x13_l\xc9" +
|
||||
"F\xddvt\xa3\xd0\xc7\xe9\xad=fQ\xcf\x8d\xd0\xed" +
|
||||
"\xea\xb9&\x9b[h\x0f\xf9\xda\x01\x00\x14d\xb9\x03\xa0" +
|
||||
"U/\x18\xa6\xc5\xdc\xbcn\xe7H(\x10s\xce\x96A" +
|
||||
"\xad\xa8\x199\x16\x1e4\xe9\xe2\x83\xbc\x03\xb2\\\x8e\xf9" +
|
||||
"Z\xcc\xda\xb3{4K\x13K\xb6Z\x1f\xeac\xc9\x00" +
|
||||
"\x80\xbaXD\xb5'\xa6\x8f\xdb\x96\x01\xa8\xcbET\xef" +
|
||||
"\x88Y\xba\xbf\x03@\xed\x11Q]-\xa0kZzA" +
|
||||
"7:\x19\x88V\xdc`\xb6ch%\x06\x00\x81\xc2\xb6" +
|
||||
"\x98eR\xa2\x8d\xa9\x08\xa5\xab4Us\xb1\x00]\xac" +
|
||||
"X4o7\xadb~\xa5w\x8eI\xda\xe6\xa6\x0c\x97" +
|
||||
"I\xe3X\x9e\x1b\x87\xe4\xd6sl~\xc5f\xde\xba\x8a" +
|
||||
"\xc5\x0d9\xbb\x97\xd9\x95\xa2c\x03\xa8\x89P\xfc\x86\x16" +
|
||||
"\x00\xb5VD5-`\xab\xc5\x190\x15\x81z\xd5U" +
|
||||
"/\xa7\xeb\x8aa\xb1\x82n;\xcc\xf2\xc8\xb3[I\xe1" +
|
||||
"%;~ \xf9_JDu\xba\x80n\xc1\xd2r\xac" +
|
||||
"\x87Y\xa8\x9b\xf9\x15\x9aafE\x96\xc3\x1a\x10\xb0f" +
|
||||
"bOZ\xaa\xe9E\x96\xf7\xa4\x9b\x9f\xcb\xf0\xff)z" +
|
||||
"\xeb]\xd7\x0b\xdf\x81(|\x1b\xf0K\xd7\x8f\xdfMQ" +
|
||||
"\xfc6\x08_\xb8\x17\x07p\x83\xf8\xb9\xeb\x870E\x84" +
|
||||
"#\xa2\xba\x95\"\xa2R&\x9d\xda \x9a\x16\xa6\"\x94" +
|
||||
"\xf4\xb5\xc3\xf2\x05\xd2\xb4\x01\xad,G\x8a\xc6T\x90\xed" +
|
||||
"=\x06)o\x0ec**e\xfce\x16[\xcf,\x9b" +
|
||||
"\xf5@\xd227\x8e`*\xca\xfaUZ\x9fz\xb5Z" +
|
||||
"\x0f\x0c\x1d\xae\x9ax\xbd\xc5r\x1ed\xf8\xcb{2\x9e" +
|
||||
"\xd1\xd2\xa1\xd1\xee\x99\x19\x01Z\x18$\xdb\x06\x01\xd4\xad" +
|
||||
"\"\xaa\xbbcA\xb2\x8b4\x7f\x9f\x88\xea~\x01e\xd1" +
|
||||
"\xc7\xc3}\x14N{ET\x0f\x0b('\x12i*f" +
|
||||
"\xe5C\x14N\xfbET\x8f\x08ca\x8f\xadg\x86\xb3" +
|
||||
"X/\x80\xc4\xec\x88JW\\\xac\x17\x18\x88\xf6\xffB" +
|
||||
"\xc0\x8d\xd1\x87\xaf\x8dP\x0f1\xe7%\xe9\xeaET\x1b" +
|
||||
"\x09\xd8\xe9+s\x08\x02\xe8\xb4\xb0d\xbe\xfci\x9d\xf4" +
|
||||
"\xaf\x0f\xd3=\xfe.\x96\x8f\xd4\x8d\xe1a\x87\xe8\xb0\x83" +
|
||||
"\"\xaa?\x8a)\xfd\xa8\x05\xa0\x1e\x11Q}B@\xf4" +
|
||||
"u\xfe\xd81\x00\xf5\x09\x11\xd5\x9f\x91\xce\x05O\xe7\xcf" +
|
||||
"\xcc\xa5\x0eKD\xf55\xd2\xb9\xe8\xe9\xfcU\x0a\xbe\xd7" +
|
||||
"DT\xdf\x12P\xaeI\xa4\xb1\x06@~\x93\xecxF" +
|
||||
"D\xf5\xddK\xe1Z\xaehV\xf2CE\x0d2\x16\xcb" +
|
||||
"w/\x0e\xe9F\xa5\xd4c\xb1\xf5:\x9a\x15\xbb\xddq" +
|
||||
"XI*;v\x90\xa2\x92\x8eV\xb0q*`\x8f\x88" +
|
||||
"\x98\x8a\x8aN@\"\x86{\xa2\xc5\xf2\xab\x98e\xeb\xa2" +
|
||||
"i\x84YF7\x1cf8\xcb5\x90\x06Y1\xa4N" +
|
||||
"\x80B\xbd~,Q$\xf9\xb0`F\xc8\x89\x05\x02\xfc" +
|
||||
"\xe9\xae\xeb+q\x09\xe9\xa6MDu\xb9\x80\xcd\xf8%" +
|
||||
"\x91I\x8f\xdd\xbd\x00j\x97\x88j\x9f\x80\xcd\xc2\x17D" +
|
||||
"&M\xaa\x03\x11\xee'\x87\x1d\xa7\x8c\xa9\xa8\x18\xf5\x8d" +
|
||||
"\xbd\x81\x0d\xdafn-\x03$\xf8\x0c+#\xff\xeb\xb0" +
|
||||
"\x0f\xe7 \x16\xf3\x98\x8a\xba\xc9*O\x11/\x95\xcb[" +
|
||||
"\xa9r0-\x9e*\xa3\xc4us$D\xe0\x1d\xdd\x03" +
|
||||
"\x91\x04\xb2\xd0\xe6\x89\xa5\x0eF\xf7\xcf\xe4\xb4\x8a\xcd\xc6" +
|
||||
"\x16!\xedC\x0e\x88\xcc\x0aq\xd7\x1e6+\xc5|/" +
|
||||
"\x03\xc9\xb1F\x10A@\x9c\x18\x8d\x17\x9b]1\xc5{" +
|
||||
"n<~\x82\x0d\xf3\xeb@<\xbf\xfa\xea\xef'\xf5\xf7" +
|
||||
"\x89\xa8\x96\x05t\x8b\x84gF\x97\xc9\xc3=\xb8\xaeG" +
|
||||
"\xec1\xb9sJ \xa0\x04\xe8V\xca\xb6c1\xad\x04" +
|
||||
"\x18z\x1b\xf1O\xbd\x8a\xb4U\x05\x9f=Z\x92\xc7\xfd" +
|
||||
"\xff\xa5\"\xe1\xea\xb3\xbd\x97y\xc7\xe4\xfac\xb1\xd4\x9b" +
|
||||
"\xf3W#_\xdei\x1a\xd2U\xd7s>\x82y\xd9f" +
|
||||
"\xbe_=P\xa9\x19\xa4\xe19\x946f\x8b\xa8\xde\x14" +
|
||||
"O\xc3\xf3HE7\x88\xa8~C@\x89Y\x94Q\xc3" +
|
||||
"\x99\x80w\xe8\x16\xdb\xab]1\x15M|.\x7f\x9dX" +
|
||||
"Y\xaf\x9b\xc6En83\x0a\x97\xd0\x84\xdd7\xc7\xec" +
|
||||
"\x1a\x98\xf0\xb6\xc1\xc8\xae\xd2Z6\x12X)\xc3J\x9a" +
|
||||
"\x1e\xa1\x91o\xdcv\x90\xbe\x1d\xf1LX\xfe\xfae\x82" +
|
||||
"W$\xb4z\xd6\xa2K\xc6\xf2\xech,\xa5\x06\x97\xdc" +
|
||||
"E\xdd\xc4n\x11\xd5\x83\xb1K\x1e\xe8\x88\xa5\xd4 \xcf" +
|
||||
"\x1e\"\x03\x1f\x16Q}T@\xf4\xd3\xecq\x82\xfcG" +
|
||||
"ETO\x0a\x1c\xb0\xbb\xda;M\x03\xfdK\xd8\x00a" +
|
||||
"G1\xcc4\xcb\x19d\x1a:\xdd\x86\xc3\xac\xf5\x1a\x16" +
|
||||
"\x03H\xd8\xe2\xe8%fV\x9c\x10\"J\xdaF^\x82" +
|
||||
"a\xbe\xcb[%i\x8e\x8du `\x1dE\xa4\xcd\xac" +
|
||||
"N\x8b\xe5\x91\xac\xa1\x15{4\xd1\x19\xbe\x12\x05\x8d\x05" +
|
||||
"\xf1\xe48\xea\xa1\x02n\xb3\x88\xea}\x04%\x18\x9b;" +
|
||||
"\xc9;\xd7\x80\xc0\x91\x84d^\xd7\x11\x95t<!\xd6" +
|
||||
"T5e<!N\xa2\x1a\x86\xb4\xb3CDu\xaf\x10" +
|
||||
"\\\xad\xcb\x84V/B\xabM\xed7=[\x085u" +
|
||||
"\x16\xc9\xeb\xd7\x0b:\x9aF\x1fW\x14F\x9a\xca\x99\xa5" +
|
||||
"\xb2E\xae\xac\x9b\x86Z\xd1\x8a\xba\xe8\x8c\x84\x0b'\xd4" +
|
||||
"\x05A\x92\x17\xca+\xcb\x19n,R\xc6-\x812\x94" +
|
||||
"\x11\\\x06\x90\xdd\x88\"fw`\xe4.\xca6\xec\x00" +
|
||||
"\xc8n&\xfa}\x18y\x8c\xb2\x13\xa7\x01d\xb7\x12}" +
|
||||
"7\x86\xbd\xaa\xb2\x0b\x1f\x07\xc8\xee&\xf2A\x8cJ\x05" +
|
||||
"\xe5\x00\xdf~?\xd1\x8f`T-(\x0f\xe1\\\x80\xec" +
|
||||
"A\xa2\x9f$\xfa$\x81kR9\x81k\x00\xb2O\x11" +
|
||||
"\xfdy\xa2K5i\xe4s\x1f\xb4\x00\xb2?#\xfa\xcf" +
|
||||
"\x89^\xdb\x98\xc6Z\x00\xe5%N\x7f\x91\xe8\xaf\x11\xbd" +
|
||||
"\xae)\x8du\x00\xca\xab\xb8\x1d \xfb\x0a\xd1\xcf\x10}" +
|
||||
"2\xa6q2\x80r\x1a\x1f\x04\xc8\x9e!\xfa\xbbD\x9f" +
|
||||
"2)\x8dS\x00\x94\x7f\xe6\xf7y\x8b\xe8\xe7\x88^\x9f" +
|
||||
"Hc=\x80\xf2\xafx\x0c {\x8e\xe8\xbf!z\x83" +
|
||||
"\x94\xc6\x06\x00\xe5\x03.\xd7\xaf\x89^+\x848\xd8\x9d" +
|
||||
"\x8f\xc31\xb9\xa1\x1e\x95#\xa2i\x87\xae\xc0\xfc\x1e\x16" +
|
||||
"\xbd\\\xd1c&\xa9\x89\xc5d4m\x06\xc4$\xa0[" +
|
||||
"6\xcd\xe2\x8a\xb10\x7f\xb9\x8a\xc8w#H\x9aFw" +
|
||||
">\x8cK\xcf\xf9\x96\x9b\x90\xc9i\xc5\xeerT#\xd9" +
|
||||
"\xed\x15\xc7\xac\x94!\x93\xd7\x1c\x96\x0f\x13\xb5U1\x96" +
|
||||
"Zf\xa9\x0f\x99U\xd2\x0d\xad\x08\xe1\x97\x89|1Y" +
|
||||
"\xa9\xe8\xf9p\xef\x09\x0b;w\x88iN\xc5b6\x89" +
|
||||
"v\x89\x8c+T{t\xa6\xdc\xd2\xa7\x15\xaaF\x11s" +
|
||||
"\xa3\xf4\x10\xa2\xdd\xbc\x9b\xa3\xec\x90\x8cGaf\xbdV" +
|
||||
"\xac\xb0+)\x06'lnz[\xbd\xe6\xe8r=p" +
|
||||
"08\xbb|5\xdf_\x95y\xbd|x\xd1\xdc\xa5#" +
|
||||
"\x126\x94\xd5\xf2g1]B\x94\xf3\x02k\x0d\xf9=" +
|
||||
".dh\xef\x98\xdf\x84\x93M\xdfo\xaeT\x13\x05\xe6" +
|
||||
"x\xbf\xba\x8d!\x93\xca\x03I+\xd9_qu/\xb3" +
|
||||
"\x93W\xa2\xc5hVy\xf9\xfc\xdd\xd5\xd7\xd7\x13\x8d;" +
|
||||
"D\x0f\xfco\x0a\xf1\xae\x1d{\x01\xb2m\x14\xb8\xcb1" +
|
||||
"\xd4\xa1\xd2\xcdq\xa7\x8b\xc8}\x18U\xbd\x8a\xca\xf1\xa5" +
|
||||
"\x87\xe8\xab1\xea\x8b\x94;9.\xac&\xfa0\xc7\xbb" +
|
||||
"v\x0f\xef\x18\xdf>O\xf42\xc7;\xf4\xf0\xae\xc4\xf7" +
|
||||
"/\x12}c\x1c\xef*8:\x06~%\xd1\xc3\xbbm" +
|
||||
"\x1c\xa7v\x10}/\xc7\xbb\x84\x87w{\xf0i\x80\xec" +
|
||||
"^\xa2\x1f\xe6xW\xe3\xe1\xdd!|\x0e {\x98\xe8" +
|
||||
"\x8fr\xbc\x9b\xe4\xe1\xddq\xce\xffh\x88\xb3S:<" +
|
||||
"\xbc;\xc1\xf11\xc4Y\xb7b\x15\xb3\x8e\xa5\x1b\x80\x85" +
|
||||
"(6r\xe5o3Vn\x87dQ_\xcf\xc2\\\x94" +
|
||||
"\xd7\xb5\xe2\xe2\x8aV\x84L\xd6\xd1rk\xa3\xd2\xbeh" +
|
||||
"wiF\xde\xc6am-\xa3\x0c&\xc5s\xbdS\xb4" +
|
||||
"W1K\x1f\x02\x8c\x9a\x81\xb0\xf6I\xf6\x98fuI" +
|
||||
"\xc4kJfy\xe0\x17~+i\x1b\xbb\xf3E\xd6\x89" +
|
||||
"A\x05$\x1aQ\x06\xd5\xe9\x8bi\x18\xe8\x95%}z" +
|
||||
"fl\xbdQ\xf6\xdb\x8b\xa0n\xe9k\xad*H\xd8\xc6" +
|
||||
"2\xcb9\x9d&\x1a\x8enT\xd8E\x1b\xe4\x86+\xc6" +
|
||||
"Z\x96_\x82F\xce\xcc\xebF\x01.\xeak\xc4KM" +
|
||||
"\x99b\x85\x1a\x8ff\x8c=\xd3\xc9sZ@\xe0\xd0E" +
|
||||
"e\x87\xdc\x12M\x07Zs|U\xab\xc54;\xd6\xd8" +
|
||||
"Np\x9a?\x15\xf5\x82\xcc\x9b\x04\xd4\x00\x84OZ\x18" +
|
||||
"<\x0b\xc8'6\x81 ?&a\xf4\x9a\x82\xc1\xe3\x89" +
|
||||
"\xfc\x90\x05\x82|@B!|k\xc4\xe0\x9dP\xde5" +
|
||||
"\x0a\x82\xbcSB1|\xfe\xc3`\xe6.\x8ft\x80 " +
|
||||
"\x97$L\x84o\xa1\x18\x0c\xece\x8dJ\xab;%\xac" +
|
||||
"\x09\x1f\x161x\x15\x92o\xdb\x0e\x82\xbcDr\x83\x0e" +
|
||||
"\x0aZ=1\xda\xd0\x0d\x00\x032\x1c2\xda\xd0\x0d\xe6" +
|
||||
"T\x18tZ\x00m\xb8\xc5\x87\xe76t\x83I-$" +
|
||||
"s\x9a\xc3\xda\xa8=\xf5>\xa2\x0f\xde\xd0\x86\xf1\x09\xa8" +
|
||||
"x\xa9\x9eh\xfc\xda\xba#\xaa\xff\xc2\x11\xd6hT\xfe" +
|
||||
"\x85}\xe8\x9e\xc7\xe3\xa5\xb5?N9\xb4\xdd\x1f\xc6\x9c" +
|
||||
"\x8c\x8dSNP\xbd}RD\xf5\x0d!*\x1a\x02\x9f" +
|
||||
"\x0e\x86\x86hZAc<\xc1\xec\xd0\xf7|\xbf\xec\xad" +
|
||||
"\x9e \xbays\x98\x97\xc5\xe8meC\x94\x0e\xe2c" +
|
||||
"\xc5\xa9\xb1\xb1\"\x06-\xb94&{\xc4\x87\x8cS/" +
|
||||
"\xd3\xdf\xc5\x1bL\x9e\xce\x12\xdc%\x83GT\x0c\x1e\xbc" +
|
||||
"e\x99\\\xabAr\x83&\x14\x83\\\x08U&\xbb\xca" +
|
||||
"N\xbc\x97e\xfe;\xc9z\x1c\x07\xf1\xceI\x92Gz" +
|
||||
"\x02\x85\xfb\xae\x89\x8d\xf6\x8a\xa6\xdfD&W\xc4\xfb\x80" +
|
||||
"\x09t\xe5]8\xa8\xda\x93\xb4\x98\xf6\xffZ\xb8\xff\xe9" +
|
||||
"\x99\xb1\xd1[\xe0\x7fo\x12\xf1\x0d\x11\xd5wb\xad\xdd" +
|
||||
"\xdb\xcb\x00\xd4\xb7DT?\x89^\x94>\"G\xfdD" +
|
||||
"\xc4\xdeX\x89.\x7fA\x8c\x9fS!\x1bOX5\xf8" +
|
||||
"\x00@\xb6\x96\x12D\x9a'\xac\x84\x97\xb0d\x1c\x04\xc8" +
|
||||
"\xa6\x88>=^\xa07\xe1\x00@\xb6\x91\xe8\xb3\xd1\xef" +
|
||||
"\xc8\x83\xd7\xa8\x8a\x15\x81{\xd1,,\xd7\x8dq\xab\xbe" +
|
||||
"\xe0\x89\x0b\x1d\x82\xcc\x8aE\xb8?\x16_\xbb\x17\xc7\xea" +
|
||||
"\xe0p\xec\x84\xcc\xcaR\x88\xe7\xd1\x0e\xc79W1\xfd" +
|
||||
"\x9d\xc0\x1cY?\xf8\xbc\xd8\xf3k\x89\xd80\xe0Xl" +
|
||||
"N\x16\x18C}\xce\x9f?\xdd\x1d3\xc6w\x06\x01\xd4" +
|
||||
"\xd5\"\xaa\xc3\x02\x07(\xb3\xbf\x9c\xd7\xd0aK-\xb6" +
|
||||
"\xae\xc2$#7\x125\xc5\xd4\x16\xe6\xec~,SA" +
|
||||
"\xbe\xd4b\xad\xeb*,\xce\x10\xbcv\x80\xa4\x9b\xf9\x8b" +
|
||||
"\x9e9\xc6\xa9,og\x83Y3\xb7\x969c^\x81" +
|
||||
"\xaa^*{\xa3\xa7\x8e\xf0\xa1\xb27\xfeP\xe9\xc3\xda" +
|
||||
":r\xf0\xb2\x88\xea\xe6\x18\xac\x8d\x8cF\x1d\xf5\xf8\xa5" +
|
||||
"\xc4\xffL\xf6\xffJ\x8fuTHKWRd\x86\x7f" +
|
||||
"D\xf4\x15\x07\xfdW\xda\x13DO\xd0W9\x1c\x83\x10" +
|
||||
"k0\xf6'&t\x88\xe0o\xfe_\x01\x00\x00\xff\xff" +
|
||||
"\x86\xbe\xf5t"
|
||||
const schema_db8274f9144abc7e = "x\xda\xccZ{\x90\x15ev?\xa7\xfb\xde\xe9\x19`" +
|
||||
"\xb8\xb7\xed\xb1\x18X`\x041+\xac\x10u\xd6\xc4\x9d" +
|
||||
"$;O\xd8\x19\x16az\xee\x0c\xba#\xa6\xec\xb9\xf7" +
|
||||
"\x9b\x99\x86\xbe\xdd\x97~\x00CpA\x0a\xa2L`\x05" +
|
||||
"\x17R\xe0\xe2\x16\xe0\x12\x1fq\xb3\xe2be5jI" +
|
||||
"\xb2\x1b$\xabQ6\x98\x92\x8dVT\xb0Rk\xad\xe5" +
|
||||
"\xa2\xa6,Sj\xa7N\xbf\xe7\xce0\x03k\xfe\xc8?" +
|
||||
":u\xee\xe9\xefq\x1e\xbf\xf3;\xe7\xe3\xfa\x9d\x93\x9a" +
|
||||
"\xb8\x1b\xd2'\xab\x01\xe4C\xe9\x0a\x97-\xf8\xd5\xc6C" +
|
||||
"\xd7\xfc\xd3V\x90g \xba\xdf}vi\xcd\xa7\xf6\xd6" +
|
||||
"\xff\x804/\x00\xd4\x9f\xaa\xd8\x88\xd2\x9b\x15\x02\x80t" +
|
||||
"\xb6\xe2\xbf\x00\xdd\xf4\x1f\xbc\xf6V\xe9-a\x1b\x883" +
|
||||
"\x92\xca\x1c)?',E\xe9\xb4@\xca/\x0b\xeb\x01" +
|
||||
"\xdd?-\xber\xe4\x8f\xf6\xfd\x92\x94\xb9X\x19\xb0\xfe" +
|
||||
"\xa6\xca\x8d(uT\x92\xe6\xe2\xca\x15\x80\xeeG{k" +
|
||||
"\xff\xf6\xf0\xbf\xbe\xb8\x1d\xc4\xaf\"\x04{\xdfQ\xf9k" +
|
||||
"\x04\x94\xd6V\xfe\x04\xd0\xfd\xb7\xeb7\x9d\xbf\xf3\xa3=" +
|
||||
"\xf7\x8e\xdc7Ezb\xd50J\xf3\xab\x04\xe0\xdd\x07" +
|
||||
"o\xaf\xf9\x17<\xf4\xc9\x1e\x10\xaf\xa5e\x90~NW" +
|
||||
"M\xe2\x00\xa5YU\x8d\x80\xee+\xd7=\xfb\xcc\xee\x9f" +
|
||||
"\xde\xf3\x03\x90\xbf\x8a\x08\xfe\xf7\x7fV\xf5?\xb4\x8f\xec" +
|
||||
")\\\xf8\xd1\xd7R?~\xe5\x8a\x1fz\x0a\xee\xd1\xd3" +
|
||||
"\xb7>\xb9\xfb\xa7W\xbd\x07=\x9c\x80)\x80\xfa\xa1*" +
|
||||
"\x93t\xb7W\x91-\xf6\xbe\xfe\xdc\xf2\xe2\x9e\x07\x8e\xf8" +
|
||||
"\x87\xf6\xd6b\x938\x0eR\xee\xb6\x8eO\x8a=\x0f\xe5" +
|
||||
"\x1e\x0a\xae\x93\xa6\x9f\xbe3\xe9C\x04\xac/N\xaaC" +
|
||||
"@\xf7\xa6_\xbf\xbb\xe2\x96'\xfb\x1f\x0e4\xbc\x93\xee" +
|
||||
"\x98\xbc\x91Nzt2\x1d\xe4\xc5\xf5\xd9\x9d\xcd\x7f|" +
|
||||
"\xdf\xc3\xe5n\xf1\xd6:5y\x18\xa5\xb7'\xd3\x9fo" +
|
||||
"N\xbe\x95\xd6\x1b\xfe\xc6s+?\xfaK\xeb1\x90\x17" +
|
||||
"b\xca\xfd\xf9\x8es\xeb\xe6?\xda\x7f\xd2;7\x0fP" +
|
||||
"\xdfS\xfd+:\xb7ZM\xb6\xac\xfe\x87\x05\xcb\xef;" +
|
||||
"\xbf\xec\x18-\x9d\xf0\x8b\x7f\x88\xaa\xa9\x0d(M\x9fJ" +
|
||||
"\xae\xb9r*i\xbfz\xdd\xca\xe7\x9f\x7fb\xe0X\xf9" +
|
||||
"A<\x97?5u)J\xa7<\xed_x\xdaWv" +
|
||||
"\xe0\x1b/\xdc\x90\xfa\xfb\xa4#\x872\xef\xd1\xe6\xbb2" +
|
||||
"\xa4p\xfbgO\xfd\xe3\xe2\x0f\xce<\x9dt\xd1\xc2," +
|
||||
"G\x17o\xce\xd2\xc5{\x87\xb1\xf8FC\xd3\xf3 _" +
|
||||
"\x8b\xe8\xae\xde\xb7\xc9n\xdf\xbf\xcb\x85\x1e\x14\x90\x03\xa8" +
|
||||
"W\xb3\x1bi1'K\x016\xeb\xfd\x96j\xfd\x83\xad" +
|
||||
"/\x94E\xa3\xb7\xeb\xe9\xecR\x94\xde\xcd\xd2\xd1\xde\xce" +
|
||||
"\xfe\x04\xf0\x93\xc7\xee\xd9\xddq\xae\xed\xa4<\x03S\xe5" +
|
||||
"\x97\xbeK\xdc\x88\xd2\x1e\x91\xfe\xdc%z\xfe\x89,X" +
|
||||
"\xa6\xee\x07\xfa\x15\xabQ:}\x05\xfd\xf9\xf2\x15\x9e\xfa" +
|
||||
"\xd2\xdb\xbf\x7f\x7f\xfa\xdd\xef\x9f,7)\x85x\xfdY" +
|
||||
"\xc9D\xe9}\x89\xfe\xfc\x8d4\x8d\x07tg<\xf1'" +
|
||||
"\x7f\xd7R8\xfb\xcb1\xb2HR\xa7}(9\xd3\xe8" +
|
||||
"\xaf\xb5\xd3\xe8\x8e\xe7\x16\x1e\xfb\x8b\xdf\xec:}&\x19" +
|
||||
")/O\xf3B\xf6\xedid\xb0{\xbe6\xb4q\xf9" +
|
||||
"5\xc3\xaf\x95;\xc8\xd3\xc4\xdaa\x94\xa6\xd7z\xee\xac" +
|
||||
"\xa5\xe5\xb8w\x95\xe9[\xfe\xfd\x9bo$\x82v{\xed" +
|
||||
";\x08)w\xf9\xca\xdbWW\xddu\xee\\r\xa3\xa1" +
|
||||
"Z\xdfu\xb5\xb4\xd1q\xf1~\xe9\xd9\xc3\x7fs\x9e6" +
|
||||
"\x12\xca\xcd\xfd\xe3\xda^\x94N\xd4z\xe6\xa9}\x98\x83" +
|
||||
"D\xf2\x8c\x158O\x7f\xa5\x01\xa5S_\xf1\x02\xe7+" +
|
||||
"t\xae\x9b\xeelf\xabn\xbe\xed=\x10g\xf0#\xb0" +
|
||||
"\"=\xb3\x01\xa5+gz\x99>\xf3\x1e\x94\xe6\xcf\x12" +
|
||||
"\x00\xdc\xef\x0d\xf4\x9e\xba\xd0z\xf8w\xe5\x8b\xfb\x880" +
|
||||
"\xab\x01\xa59\xa4W?k\x96\xe7\x9f\xfa\x1b\xfe\xea\xfd" +
|
||||
"}\x0f\xb5^\x18\xb5\xba:\xbb\x05\xa5\xa1\xd9t\x0eg" +
|
||||
"\xf6\xb7\xa4\xa3\xb3\xbd\xc5\xbf\xdb\xb6\xe2\x1bsO|\x98" +
|
||||
"\xb4\xc4\xae\xd9\x94\xbe\xd2\xe1\xd9d\x89\xfe\x9b\x7f\xfb\xad" +
|
||||
"k\xbe\xf7\xcf\x1f\x96\xf9\xcfS<1{\x01J\xa7\xbd" +
|
||||
"\x15_&\xe5\x0f\x96\xfc\xf0\xcc\x8c\xcc\x8c\x8f\xcb\x0eJ" +
|
||||
"\x98Z\x7fa\xf6j\x94\xd2u\x9e\xa3\xeaN\xd2Ao" +
|
||||
"{\xe7\x81\xf5\x8d?\xf8\xf8\x13\xba\x17_\x06t\xff}" +
|
||||
"U/JUsh\xe5\xf4\x1c\xca\xa5e\x8f\x9f\xfd\xe6" +
|
||||
"\xe0\xbe\x17?\x1d\x13\xba\x8f\xcd\xd9\x8a\xd2/<\xed\x13" +
|
||||
"s\x08\xae\xfeZ8xn\xcb\x7f\xfe\xf9g\xc9[=" +
|
||||
":\xf7\x1d\xba\xd5ss\xe9V\x9b>8\xd0~\xdf\xaa" +
|
||||
"\xc7\xbfH*\xbc9w+\xa5\xe6\xa7\x9eB\x94\x8cc" +
|
||||
"E\xda\xf4\xab[P\x9a\x7f5\xedw\xcd\xd5\xa4m;" +
|
||||
"\xba\xce4\xb3\x94\xca\xffa\xf8g~Q^)\xe9\xa5" +
|
||||
"\x86f\xc7\x1ed\xba\xad\xe6\x15\x9bu\xb1F\xabd\xe8" +
|
||||
"\x16\xebD\x94\xb3|\x0a \x85\x00\xa2\xb2\x1a@\xbe\x93" +
|
||||
"GY\xe3PD\xac!\xb8\x16U\x12\x0e\xf2(\xdb\x1c" +
|
||||
"\x8a\x1cWC\x88 \xae\x9d\x0b k<\xca\x1b8D" +
|
||||
"\xbe\x86\xf0Nt\xee\x07\x907\xf0(o\xe3\xd0-1" +
|
||||
"\xb3\xa8\xe8L\x87\x8c\xbd\xd84q\x0ap8\x05\xd05" +
|
||||
"\x99m\x0e)}\x1adXB,\xac^oc5p" +
|
||||
"X\x0d\xe8\x0e\x1a\x8ei\xf5\xe86\xaaZ\x17\xeb7\x99" +
|
||||
"\x85\x83X\x01\x1cV\x8c\x7f\xbdVC\xd7Y\xde\xce9" +
|
||||
"\xf9<\xb3,\x00\xbaYet\xb3\xf9\x0f\x00\xc8\xd7\xf1" +
|
||||
"(\xdf\x9c\xb8\xd9Mt\xb3\xaf\xf3(7q\xe8Z\xcc" +
|
||||
"\\\xc7\xcce\x06\xe6\x15[5\xf4\xe5\x0a_d\xd1\xb1" +
|
||||
"\xf3\x9a\xcat\xbb\xd5\x80\x8c\xde\xaf\x0e`6N\x05@" +
|
||||
"\xcc\x8e\x7f\xb0\xc5\x1bT\xcbV\xf5\x81nO\xde\xd8i" +
|
||||
"hj~\x88N7\xc5\xb3\xe4\xac\x06ZC\xbc\xb2\x17" +
|
||||
"\x009Ql\x01hT\x07t\xc3dnA\xb5\xf2t" +
|
||||
")\xe0\xf3\xf6\xe6>ES\xf4<\x8b6\xaa\x18\xbd\x91" +
|
||||
"\xbfA\xce\xbb\xc7\"%\xe1\xedy\x9d\x8a\xa9\xf0EK" +
|
||||
"\x9e\x12\xd9cq/\x80\xdc\xc6\xa3\xdc\x99\xb0\xc7-K" +
|
||||
"\x01\xe4e<\xca\xb7%<\xdd\xd3\x02 w\xf2(\xaf" +
|
||||
"\xe2\xd05Lu@\xd5[\x19\xf0f\xd2a\x96\xad+" +
|
||||
"E\x06\x00\xa1\xc16\x1b%2\xa2\x85\xd9\x18\xa5\xcb," +
|
||||
"\x95\x1e}\x81v\xa6i\xc6\xad\x86\xa9\x15V\xf8\xfb\x18" +
|
||||
"dm\xcf\x95\xd1g\xc2\x18\x9e\xf7\x9cC\xf7V\xf3l" +
|
||||
"\x91c1\xff;\xc7\xf4\x1c9\xaf\x8bY\x8ef[\x00" +
|
||||
"r*\xba~u\x03\x80\\\xc9\xa3\\\xc3a\xa3\xe9)" +
|
||||
"`6\x06\xf5\xb2\xa3NdkG7\xd9\x80j\xd9\xcc" +
|
||||
"\xf4\xc5\xf3\x1a\xc9\xe0E+\xb9!\xc5_\x96Gy&" +
|
||||
"\x87\xee\x80\xa9\xe4Y'3Q5\x0a\xcb\x15\xdd\xc8\xf1" +
|
||||
",\x8fi\xe00=~$-QT\x8d\x15\xfc\xdb-" +
|
||||
"\xca\xd7y\xff\xa7\xec\x9d\xe2\xba~\xfa\xf6\xc6\xe9[\x8d" +
|
||||
"_\xb8A\xfen\x8c\xf3\xb7\x9a\xfb\xdc\x1d\x9d\xc0\xd5\xfc" +
|
||||
"gn\x90\xc2\x94\x116\x8f\xf2\x16\xca\x08\xa7D6\xb5" +
|
||||
"\x807L\xcc\xc6(\x19X\x87\x15\x06\xc8\xd2:4\xb2" +
|
||||
"<\x19\x1a\xb3a\xb5\xf7\x15\x84\x821\x88\xd9\x98\xca\x04" +
|
||||
"\x9f\x99l\x1d3-\xd6\x09\x19\xd3\xd80\x84\xd9\xb8\xea" +
|
||||
"\x97Y}\xea\xe5Z=tt\xf4\xd5\xf8\xdf\x9b,\xef" +
|
||||
"CF\xf0yg\x9d\xef\xb4\x9a\xc8iw\xcd\x8d\x01-" +
|
||||
"J\x92\xbb\xfb\x00\xe4-<\xca;\x13I\xb2\x83,\x7f" +
|
||||
"/\x8f\xf2^\x0eE>\xc0\xc3=\x94N\xbby\x94\x0f" +
|
||||
"r(\xa6R5Df\xc5\x03\x94N{y\x94\x0fq" +
|
||||
"#a\x8f\xadc\xba\xdd\xa6\x0e\x80\xc0\xacXJGl" +
|
||||
"S\x07\x18\xf0\xd6\x97M\xb8\xca\x09\xeca\xf4Y\x86\xc6" +
|
||||
"l\xd6\xc6\xf2\x9aB\xb9\xb3\x8e\xf9\xbf\x07\xc8:VT" +
|
||||
"\xd3\xb5\xa7\xf0(\xd7\x12\xe2\xd3\xaf\xcc&l\xa0cD" +
|
||||
"\\z\xe2\xbco\xa5\xff\x06\xbbt\x06\xab\x98\x01\x84\xd7" +
|
||||
"F\x9b\x1d\xa0\xcd\xf6\xf3(\xff(\xe1\x8d\xc3&uT" +
|
||||
"<\xca\x8fs\x88\x813\x1e=\x02 ?\xce\xa3\xfc3" +
|
||||
"r\x06\xe7;\xe3\xa9\x05\x00\xf2\x13<\xca/\x913x" +
|
||||
"\xdf\x19\xa7(+_\xe2Q~\x9dC1\x9d\xaa\xc14" +
|
||||
"\x80\xf8\x1a9\xf8\x0c\x8f\xf2[\x17\x03\xbc\xbcf8\x85" +
|
||||
"~M\x81:\x93\x15:\xda\"\xb9\xee\x14;M\xb6N" +
|
||||
"E\xc3\xb1\x9am\x9b\x15\x85\x92m\x85\xb5+c+\x03" +
|
||||
"\x16N\x05\xec\xe4\x11\xb31\x1b\x05$a\xb4&\x9a\xac" +
|
||||
"\xb0\x92\x99\x96\xca\x1bzT~T\xddf\xba\xbdL\x01" +
|
||||
"\xa1\x8fi\x91t\x1cx\xea\x0a\x92\x8cR,\xc0\x0b#" +
|
||||
"\x86T\x1c\xa0J0\xd3u\x03#.&\xdb4\xf1(" +
|
||||
"/\xe3p\x16~Ab\xb2cG\x17\x80\xdc\xce\xa3\xdc" +
|
||||
"\xcd\xe1,\xees\x12\x93%\xe5\xde\xb8 d\x06m\xbb" +
|
||||
"\x84\xd9\x98\xa5\x06\xce^\xcf\xfa,#\xbf\x86\x01\x12\xae" +
|
||||
"F\x94)\xf8u0\xc0y\xe0\xb5\x02f\xe36\xb3," +
|
||||
"R\xf8\x8b\x15\xf9F\xa2\x14\x86\xe9\xd5\xd0\xb8\xa2\xdd\x18" +
|
||||
"_\"\x8c\x8e\x8e\xde\xf8\x06\"\xd7\xe4_K\xee\x8b\xcf" +
|
||||
"_\x97W\x1c\x8b\x8dd'\xcd\xfd6\xf0\xcc\x8c\x00\xd9" +
|
||||
"\x1a4\x1c\xad\xd0\xc5@\xb0\xcd!D\xe0\x10\xc7\x87\xe9" +
|
||||
"6\xa3=ax?\x8c\xc7\xae\xbcQ\xe1\xedM\x16\xde" +
|
||||
"\xc0\xfc=d\xfen\x1e\xe5\x12\x87\xaeF@\xa7\xb7\x1b" +
|
||||
"\x1e\x0e\x84\xc7\xf5\x85\x9d\x86\x17\x9c\x02p(\x00\xbaN" +
|
||||
"\xc9\xb2M\xa6\x14\x01\xa3h#\xfd\xa9\x97Q\xcf\xcap" +
|
||||
"\xb5S\xc9xy\xff\xff\x89=\\>\x0d\xf0\xc1k\x04" +
|
||||
"\x098\x92\xa8\xc9\xf9\xe0k\xf4>o5t\xe1\xb2\x89" +
|
||||
"^\x80`~\x19Z\x14\xd0\x0a\xe2\xa0a}\x9eO\xf5" +
|
||||
"d\x1e\x8f\xf2\xf5\xc9\xfa\xbc\x90Lt-\x8f\xf2\xd79" +
|
||||
"\x14\x98I\xa56\x1a\x16\xf8\x9bn\xb6|R\x8b\xd9x" +
|
||||
"\x144\xf1q\x12|_5\xf4Qa87N\x97\xc8" +
|
||||
"\x85\x1d7&\xfc\x1a\xba\xf0\x96\xbe\xd8\xaf\xc2\x1a6\x14" +
|
||||
"z\xa9\x8e\x15\x155F\xa3\xc0\xb9\xcd |;\xd6\x19" +
|
||||
"\x97\x17\x07\xfc\xc1g\x0f\x8d\xbe\xb7\xe8\x90\x89\x02<\x9c" +
|
||||
"\xa8\xb5\xe1!wP\x9b\xb1\x93Gy\x7f\xe2\x90\xfbZ" +
|
||||
"\x12\xb56,\xc0\x07\xc8\xc1\x07y\x94\x1f\xe1\x10\x83\xfa" +
|
||||
"{\x94 \xff\x11\x1e\xe5\xe3\x9c\x07\xd8\xed\xcd\xad\x86\x8e" +
|
||||
"\xc1!,\x80\xa8\xd5\x18d\x8ai\xf71\x05\xed\x0e\xdd" +
|
||||
"f\xe6:\x05\xb5\x10\x126\xdbj\x91\x19\x8e\x1dAD" +
|
||||
"Q\xd9\xe0q3,\xb4\xfb_\x09\x8ama\x15pX" +
|
||||
"E\x19i1\xb3\xd5d\x05$o(Z\xa7\xc2\xdb\x83" +
|
||||
"\x97b\xa0\x91 \x9e\x19\xc3<\xc4\xec6\xf1(\xdfK" +
|
||||
"P\x82\x89\x81\x94\xb8}5p\x1e\x92\xd0\x9d\xd7\xb6\xc4" +
|
||||
"\\\xcf+\x88\xe9\xb2n\xcd+\x88\x15Dn\xc8:\xdb" +
|
||||
"x\x94ws\xe1\xd1\xda\x0dh\xf43\xb4\xdc\xd5A7" +
|
||||
"\xb4\x99PSe\xf1}\x03Z\xa5\xa2\xa1w{\x86\xc2" +
|
||||
"\xd8Ry\xa3X2)\x94UC\x97\x1dESy{" +
|
||||
"(\xfap\\[\x10$\xf9\xa9\xbc\xa2T\xe79\x8b\x8c" +
|
||||
"qsh\x0ci\x08\x97\x02\xe46 \x8f\xb9m\x18\x87" +
|
||||
"\x8bt7\xb6\x00\xe46\x91\xfc^\x8c#F\xda\x8e3" +
|
||||
"\x00r[H\xbe\x13\xa3&V\xda\x81\x8f\x01\xe4v\x92" +
|
||||
"x?\xc6TA\xda\xe7-\xbf\x97\xe4\x870f\x0b\xd2" +
|
||||
"\x83\xb8\x00 \xb7\x9f\xe4\xc7I^\xc1y\x96\x94\x8e\xe1" +
|
||||
"j\x80\xdc\x13$\x7f\x96\xe4B\xba\x86:v\xe9i4" +
|
||||
"\x01r?#\xf9\xcfI^Y[\x83\x95\x00\xd2\x09O" +
|
||||
"\xfe\x02\xc9_\"y\xd5\xf4\x1a\xac\x02\x90N\xe1V\x80" +
|
||||
"\xdc\x8b$?C\xf2IX\x83\x93\x00\xa4\xd3\xf8\x00@" +
|
||||
"\xee\x0c\xc9\xdf\"\xf9\xe4\x8a\x1a\x9c\x0c \xbd\xe9\x9d\xe7" +
|
||||
"u\x92\x9f'\xf9\x94T\x0dN\x01\x90\xde\xc6#\x00\xb9" +
|
||||
"\xf3$\xff\x1d\xc9\xab\x85\x1a\xac\x06\x90\xde\xf7\xee\xf5[" +
|
||||
"\x92Wr\x11\x0ev\x14\x92pLa\xa8\xc6t\x847" +
|
||||
"\xac(\x14X\xd0\xdc\xa2_+:\x8d\x0cu\xb7\x98\x89" +
|
||||
"\xc7\xd0\x80\x98\x01tK\x86\xa1-\x1f\x09\xf3\x131\xa2" +
|
||||
" \x8c c\xe8\x1d\x85(/\xfd\xe0[f@]^" +
|
||||
"\xd1:J1G\xb2\x9a\x1d\xdbpJPWPlV" +
|
||||
"\x88\x0a\xb5\xe9\xe8KL\xa3\xd8\x8d\xcc,\xaa\xba\xa2A" +
|
||||
"\xf4\xcbx\xb1\x98q\x1c\xb5\x10\xad=.\xb1s\xfb\x99" +
|
||||
"b;&\xb3\xe8j\x17\xa9\xb8\\yD\xd7\x95\x1a\xba" +
|
||||
"\x95\x81\xb2\x19\xc5\x82\xb8<Dh\xb7\xf0\xc6\xb8:d" +
|
||||
"\x92YX\xb7N\xd1\x1cv)dp\xdc\xae\xa7\xab\xd1" +
|
||||
"\xef\x9a&j\x8e\xc3\x89\xda\xc4l\xbe\xa7\xac\xf2\xfa\xf5" +
|
||||
"p\xd4@\xa6%\xbeltW3\x18\xd2\xb4sq\xcd" +
|
||||
"\x0b\xbd\xd5\x1f4\xbfPGk'\xe2&\x1ay\x06q" +
|
||||
"s\xa9\x96\x18`\xb6\xffW\x87\xdeo\x10=\x10\x94\xa2" +
|
||||
"\xf5{~\xdd\xc5\xac\xcc\xa5X1\x1ebN\\\xbf\xdb" +
|
||||
"\xbb\xbb;\xe39\x08\xef\x83\xff\xf5\x11\xde5c\x17@" +
|
||||
"\xae\x89\x12w\x19F6\x94:<\xdci'q7\xc6" +
|
||||
"\xacW\x92=|\xe9$\xf9*\x8c\xfb\"\xe9;\x1e." +
|
||||
"\xac\"\xf9\xa0\x87w\xcd>\xde1o\xf9\x02\xc9K\x1e" +
|
||||
"\xde\xa1\x8fwEo}\x8d\xe4\x1b\x92x\xe7\xe0\xf0\x08" +
|
||||
"\xf8\x15x\x1f\xef\xee\xf6pj\x1b\xc9w{x\x97\xf2" +
|
||||
"\xf1n\x17>\x09\x90\xdbM\xf2\x83\x1e\xde\xa5}\xbc;" +
|
||||
"\x80\xcf\x00\xe4\x0e\x92\xfc\x11\x0f\xef*|\xbc;\xea\xe9" +
|
||||
"?\x12\xe1\xec\xe4\x16\x1f\xef\x8ey\xf8\x18\xe1\xac\xeb\x98" +
|
||||
"Z\xce6U\x1dp \xce\x8d|\xe9\xdb\x8c\x95\x9a!" +
|
||||
"\xa3\xa9\xebXT\x8b\x0a\xaa\xa2\xb59\x8a\x06u9[" +
|
||||
"\xc9\xaf\x89\xa9\xbdf\xb5+z\xc1\xc2Ae\x0d\xa3\x0a" +
|
||||
"&$k\xbd\xadY+\x99\xa9\xf6\x03\xc6\xcd@\xc4}" +
|
||||
"2\x9d\x86QN\x89<N\xc9L\x1f\xfc\xa2\xdf\x8a\xca" +
|
||||
"\x86\x8e\x82\xc6Z1d@\xbc\x1eWP\x95~1t" +
|
||||
"\x1d}Z\xd2\xad\xd6\x8d\xe4\x1b\xa5\xa0\xbd\x08yKw" +
|
||||
"c\x19!a\x1bJ,o\xb7\x1a\xa8\xdb\xaa\xee\xb0Q" +
|
||||
"\x0b\xe4\x07\x1d}\x0d+,F=o\x14T}\x00F" +
|
||||
"\xf55\xfc\xc5\xc6O\x09\xa2\xe6e3&\xde\xef\xc4\xf9" +
|
||||
"\x0d\xc0y\xd0E\xb4Cl\x88\xa7\x03\x8dy\xef\xabF" +
|
||||
"\x93)V\xa2\xb1\x1dg\xb7`\\\xea'\x99?\x09H" +
|
||||
"\x03Do]\x18\xbe\x17\x88\xc76\x02'>*`\xfc" +
|
||||
"\xcc\x82\xe1\xab\x8a\xf8\xa0\x09\x9c\xb8O@.z\x84\xc4" +
|
||||
"\xf0\x01Q\xdc1\x0c\x9c\xb8]@>z\x17\xc4p\x18" +
|
||||
"\x7f\xc3\xd0$\x04N\xbcK\xc0T\xf4J\x8a\xe1(_" +
|
||||
"\\K\xdcJ\x150\x1d=9b\xf8^$\xde\xb1\x15" +
|
||||
"8\xb1Gp\xc3\x16\x0a\x1a\xfd{4\xa1\x1b\"\x06\xd4" +
|
||||
"y\x98\xd1\x84n8\xc1\xc2\xb0\xd5\x02hB7\x9c\xc3" +
|
||||
"\xf0\x17\x1b\xc4xZ\xe1|\x172y\xc5fM\xd4\xbb" +
|
||||
"\xfa\xc0\x8e\x01\xb2C\x13&\xe7\xa6\xfc\xc5\x1a\xa6\xb1\x89" +
|
||||
"wKL\x0e\xa3\xc1\xd7p\xcc\x0d\xa3&u\xd7cI" +
|
||||
"\xde\x1d\xccZ\x0el\x0d&5\xc7\x13\xb3\x96cD\xc6" +
|
||||
"\x8f\xf3(\xbf\xca\xc5\x8c\"\x0c\xf8p\xd4\x88\x86\x19v" +
|
||||
"\xcd\xe3L\x1c\x83\xb4\x088q\xf9\xdc\xd1-\x18\x83\x1e" +
|
||||
"gF\x7f)\x0b\xe2Z\x91\x1cFNM\x0c#1\xec" +
|
||||
"\xd7\x85\x11\xa5%9\x9a\x9c:A\xf3\x97\xec>\xbdZ" +
|
||||
"\x97\xf2\xe25|z\xc5\xf0\x99\\\x14)\xee\xaa\x057" +
|
||||
"\xecP1,\x94P\xe6\xb2\xcbl\xd3\xbbX\xdd\x97\xa9" +
|
||||
"\xe4c\x04\x88\xbfO\x86\xa2\xd5\xbfP\xb4\xee\xea\xc4\xdc" +
|
||||
"O3\x82\x0e3\xb3<\xd9$\x8cc+\xff\xc0!\xa5" +
|
||||
"\xcf\xd0\xc7\xb4\xfeU\xd1\xfa\xa7\xe7&\xe6ra\xfc\xbd" +
|
||||
"F\xc2Wy\x94\xdfH\xf4}g\x97\x02\xc8\xaf\xf3(" +
|
||||
"\x7f\x1c\xbfC]\xa0@\xfd\x98\xc7\xae\x04\x7f\x17?'" +
|
||||
"\xc5\xcf\x88\xe5&\xabY\x1a\xef\x07\xc8UR\xf5\xa8\xf1" +
|
||||
"\xaaY\xca\xaff\"\xf6\x01\xe4\xb2$\x9f\x99d\xef\xd3" +
|
||||
"\xb1\x17 WK\xf2y\x18\xb4\xeb\xe1\x1b\x96c\xc6\xc8" +
|
||||
"\xaf\x19\x03\xcbT}LJ\x18>\x8c\xa1Mx\xea\x98" +
|
||||
"T\x14F\x82oG[\x82$G3)df\x8eR" +
|
||||
"\xbc\x80V4\xeb\xb9\x8c\x99\xf18\xee\xc8\x05\xc9\xe7\xe7" +
|
||||
"^@4\x12\x93\x82#\x89!Z\xe8\x0c\xf9\x99`8" +
|
||||
"ug\xc2\x19w\xf4\x01\xc8\xabx\x94\x079\x0f\xa0\x8c" +
|
||||
"\x9eRAA\x9b-1\xd9Z\x87\x09z~(\xee\x98" +
|
||||
"\xa9g\xcc[=X\"\xb6\xbe\xc4d\x8dk\x1d\x96T" +
|
||||
"\x08\xdfH@P\x8d\xc2\xa8\xc7\x911h\xe7\xad\xac/" +
|
||||
"g\xe4\xd70{\xc4\xdbQ\xd9\xfbfW\xfc@\x12=" +
|
||||
"ov%\x9f7\x03X[K\x01^\xe2Q\xde\x94\x80" +
|
||||
"\xb5\xa1\xe1\xb8\xdd\x1e\x9bg\xfc\xdfP\x83\xdf\xeb\x89\x8f" +
|
||||
"X\xb6p)\x0c4\xfa\xa7Ge\xf9_\xf5e\x9f\x07" +
|
||||
"\xc2\xe7\x97\x09O\x10\xbdh_\xe6H\x0d\"\x10\xc2\xc4" +
|
||||
"\xbfX\xa1M\xb8`\xf1\xff\x0d\x00\x00\xff\xff\xcb\x86\x19" +
|
||||
"\x8c"
|
||||
|
||||
func init() {
|
||||
schemas.Register(schema_db8274f9144abc7e,
|
||||
|
Reference in New Issue
Block a user