package structs import ( "fmt" "github.com/mitchellh/mapstructure" ) // ConnectAuthorizeRequest is the structure of a request to authorize // a connection. type ConnectAuthorizeRequest struct { // Target is the name of the service that is being requested. Target string // ClientCertURI is a unique identifier for the requesting client. This // is currently the URI SAN from the TLS client certificate. // // ClientCertSerial is a colon-hex-encoded of the serial number for // the requesting client cert. This is used to check against revocation // lists. ClientCertURI string ClientCertSerial string } // ProxyExecMode encodes the mode for running a managed connect proxy. type ProxyExecMode int const ( // ProxyExecModeUnspecified uses the global default proxy mode. ProxyExecModeUnspecified ProxyExecMode = iota // ProxyExecModeDaemon executes a proxy process as a supervised daemon. ProxyExecModeDaemon // ProxyExecModeScript executes a proxy config script on each change to it's // config. ProxyExecModeScript // ProxyExecModeTest tracks the start/stop of the proxy in-memory // and is only used for tests. This shouldn't be set outside of tests, // but even if it is it has no external effect. ProxyExecModeTest ) // NewProxyExecMode returns the proper ProxyExecMode for the given string value. func NewProxyExecMode(raw string) (ProxyExecMode, error) { switch raw { case "": return ProxyExecModeUnspecified, nil case "daemon": return ProxyExecModeDaemon, nil case "script": return ProxyExecModeScript, nil default: return 0, fmt.Errorf("invalid exec mode: %s", raw) } } // String implements Stringer func (m ProxyExecMode) String() string { switch m { case ProxyExecModeUnspecified: return "global_default" case ProxyExecModeDaemon: return "daemon" case ProxyExecModeScript: return "script" case ProxyExecModeTest: return "test" default: return "unknown" } } // ConnectManagedProxy represents the agent-local state for a configured proxy // instance. This is never stored or sent to the servers and is only used to // store the config for the proxy that the agent needs to track. For now it's // really generic with only the fields the agent needs to act on defined while // the rest of the proxy config is passed as opaque bag of attributes to support // arbitrary config params for third-party proxy integrations. "External" // proxies by definition register themselves and manage their own config // externally so are never represented in agent state. type ConnectManagedProxy struct { // ExecMode is one of daemon or script. ExecMode ProxyExecMode // Command is the command to execute. Empty defaults to self-invoking the same // consul binary with proxy subcomand for ProxyExecModeDaemon and is an error // for ProxyExecModeScript. Command []string // Config is the arbitrary configuration data provided with the registration. Config map[string]interface{} // Upstreams are the dependencies the proxy should setup outgoing listeners for. Upstreams Upstreams // ProxyService is a pointer to the local proxy's service record for // convenience. The proxies ID and name etc. can be read from there. It may be // nil if the agent is starting up and hasn't registered the service yet. We // ignore it when calculating the hash value since the only thing that effects // the proxy's config is the ID of the target service which is already // represented below. ProxyService *NodeService `hash:"ignore"` // TargetServiceID is the ID of the target service on the localhost. It may // not exist yet since bootstrapping is allowed to happen in either order. TargetServiceID string } // ConnectManagedProxyConfig represents the parts of the proxy config the agent // needs to understand. It's bad UX to make the user specify these separately // just to make parsing simpler for us so this encapsulates the fields in // ConnectManagedProxy.Config that we care about. They are all optional anyway // and this is used to decode them with mapstructure. type ConnectManagedProxyConfig struct { BindAddress string `mapstructure:"bind_address"` BindPort int `mapstructure:"bind_port"` LocalServiceAddress string `mapstructure:"local_service_address"` LocalServicePort int `mapstructure:"local_service_port"` } // ParseConfig attempts to read the fields we care about from the otherwise // opaque config map. They are all optional but it may fail if one is specified // but an invalid value. func (p *ConnectManagedProxy) ParseConfig() (*ConnectManagedProxyConfig, error) { var cfg ConnectManagedProxyConfig d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ ErrorUnused: false, WeaklyTypedInput: true, // allow string port etc. Result: &cfg, }) if err != nil { return nil, err } err = d.Decode(p.Config) if err != nil { return nil, err } return &cfg, nil }