agent: drop atlas/scada code
This commit is contained in:
parent
091bea4922
commit
e13f3446ac
|
@ -8,7 +8,6 @@ import (
|
|||
"os/signal"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -24,7 +23,6 @@ import (
|
|||
"github.com/hashicorp/go-checkpoint"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/logutils"
|
||||
"github.com/hashicorp/scada-client/scada"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
|
@ -52,8 +50,6 @@ type Command struct {
|
|||
agent *Agent
|
||||
httpServers []*HTTPServer
|
||||
dnsServer *DNSServer
|
||||
scadaProvider *scada.Provider
|
||||
scadaHTTP *HTTPServer
|
||||
}
|
||||
|
||||
// readConfig is responsible for setup of our configuration using
|
||||
|
@ -65,7 +61,6 @@ func (c *Command) readConfig() *Config {
|
|||
var retryIntervalWan string
|
||||
var dnsRecursors []string
|
||||
var dev bool
|
||||
var dcDeprecated string
|
||||
var nodeMeta []string
|
||||
|
||||
f := c.Command.NewFlagSet(c)
|
||||
|
@ -91,7 +86,6 @@ func (c *Command) readConfig() *Config {
|
|||
"Setting this to true will prevent Consul from using information from the"+
|
||||
" host to generate a node ID, and will cause Consul to generate a"+
|
||||
" random node ID instead.")
|
||||
f.StringVar(&dcDeprecated, "dc", "", "Datacenter of the agent (deprecated: use 'datacenter' instead).")
|
||||
f.StringVar(&cmdConfig.Datacenter, "datacenter", "", "Datacenter of the agent.")
|
||||
f.StringVar(&cmdConfig.DataDir, "data-dir", "", "Path to a data directory to store agent state.")
|
||||
f.BoolVar(&cmdConfig.EnableUI, "ui", false, "Enables the built-in static web UI server.")
|
||||
|
@ -119,15 +113,6 @@ func (c *Command) readConfig() *Config {
|
|||
f.StringVar(&cmdConfig.AdvertiseAddrWan, "advertise-wan", "",
|
||||
"Sets address to advertise on WAN instead of -advertise address.")
|
||||
|
||||
f.StringVar(&cmdConfig.AtlasInfrastructure, "atlas", "",
|
||||
"(deprecated) Sets the Atlas infrastructure name, enables SCADA.")
|
||||
f.StringVar(&cmdConfig.AtlasToken, "atlas-token", "",
|
||||
"(deprecated) Provides the Atlas API token.")
|
||||
f.BoolVar(&cmdConfig.AtlasJoin, "atlas-join", false,
|
||||
"(deprecated) Enables auto-joining the Atlas cluster.")
|
||||
f.StringVar(&cmdConfig.AtlasEndpoint, "atlas-endpoint", "",
|
||||
"(deprecated) The address of the endpoint for Atlas integration.")
|
||||
|
||||
f.IntVar(&cmdConfig.Protocol, "protocol", -1,
|
||||
"Sets the protocol version. Defaults to latest.")
|
||||
f.IntVar(&cmdConfig.RaftProtocol, "raft-protocol", -1,
|
||||
|
@ -169,10 +154,43 @@ func (c *Command) readConfig() *Config {
|
|||
f.StringVar(&retryIntervalWan, "retry-interval-wan", "",
|
||||
"Time to wait between join -wan attempts.")
|
||||
|
||||
// deprecated flags
|
||||
var dcDeprecated string
|
||||
var atlasJoin bool
|
||||
var atlasInfrastructure, atlasToken, atlasEndpoint string
|
||||
f.StringVar(&dcDeprecated, "dc", "",
|
||||
"(deprecated) Datacenter of the agent (use 'datacenter' instead).")
|
||||
f.StringVar(&atlasInfrastructure, "atlas", "",
|
||||
"(deprecated) Sets the Atlas infrastructure name, enables SCADA.")
|
||||
f.StringVar(&atlasToken, "atlas-token", "",
|
||||
"(deprecated) Provides the Atlas API token.")
|
||||
f.BoolVar(&atlasJoin, "atlas-join", false,
|
||||
"(deprecated) Enables auto-joining the Atlas cluster.")
|
||||
f.StringVar(&atlasEndpoint, "atlas-endpoint", "",
|
||||
"(deprecated) The address of the endpoint for Atlas integration.")
|
||||
|
||||
if err := c.Command.Parse(c.args); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// check deprecated flags
|
||||
if atlasInfrastructure != "" {
|
||||
c.UI.Warn("WARNING: 'atlas' is deprecated")
|
||||
}
|
||||
if atlasToken != "" {
|
||||
c.UI.Warn("WARNING: 'atlas-token' is deprecated")
|
||||
}
|
||||
if atlasJoin {
|
||||
c.UI.Warn("WARNING: 'atlas-join' is deprecated")
|
||||
}
|
||||
if atlasEndpoint != "" {
|
||||
c.UI.Warn("WARNING: 'atlas-endpoint' is deprecated")
|
||||
}
|
||||
if dcDeprecated != "" && cmdConfig.Datacenter == "" {
|
||||
c.UI.Warn("WARNING: 'dc' is deprecated. Use 'datacenter' instead")
|
||||
cmdConfig.Datacenter = dcDeprecated
|
||||
}
|
||||
|
||||
if retryInterval != "" {
|
||||
dur, err := time.ParseDuration(retryInterval)
|
||||
if err != nil {
|
||||
|
@ -308,14 +326,6 @@ func (c *Command) readConfig() *Config {
|
|||
}
|
||||
}
|
||||
|
||||
// Output a warning if the 'dc' flag has been used.
|
||||
if dcDeprecated != "" {
|
||||
c.UI.Error("WARNING: the 'dc' flag has been deprecated. Use 'datacenter' instead")
|
||||
|
||||
// Making sure that we don't break previous versions.
|
||||
config.Datacenter = dcDeprecated
|
||||
}
|
||||
|
||||
// Ensure the datacenter is always lowercased. The DNS endpoints automatically
|
||||
// lowercase all queries, and internally we expect DC1 and dc1 to be the same.
|
||||
config.Datacenter = strings.ToLower(config.Datacenter)
|
||||
|
@ -449,13 +459,6 @@ func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *log
|
|||
}
|
||||
c.agent = agent
|
||||
|
||||
// Enable the SCADA integration
|
||||
if err := c.setupScadaConn(config); err != nil {
|
||||
agent.Shutdown()
|
||||
c.UI.Error(fmt.Sprintf("Error starting SCADA connection: %s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
if config.Ports.HTTP > 0 || config.Ports.HTTPS > 0 {
|
||||
servers, err := NewHTTPServers(agent, config, logOutput)
|
||||
if err != nil {
|
||||
|
@ -799,16 +802,6 @@ func (c *Command) Run(args []string) int {
|
|||
defer server.Shutdown()
|
||||
}
|
||||
|
||||
// Check and shut down the SCADA listeners at the end
|
||||
defer func() {
|
||||
if c.scadaHTTP != nil {
|
||||
c.scadaHTTP.Shutdown()
|
||||
}
|
||||
if c.scadaProvider != nil {
|
||||
c.scadaProvider.Shutdown()
|
||||
}
|
||||
}()
|
||||
|
||||
// Join startup nodes if specified
|
||||
if err := c.startupJoin(config); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
|
@ -860,12 +853,6 @@ func (c *Command) Run(args []string) int {
|
|||
gossipEncrypted = c.agent.client.Encrypted()
|
||||
}
|
||||
|
||||
// Determine the Atlas cluster
|
||||
atlas := "<disabled>"
|
||||
if config.AtlasInfrastructure != "" {
|
||||
atlas = fmt.Sprintf("(Infrastructure: '%s' Join: %v)", config.AtlasInfrastructure, config.AtlasJoin)
|
||||
}
|
||||
|
||||
// Let the agent know we've finished registration
|
||||
c.agent.StartSync()
|
||||
|
||||
|
@ -881,7 +868,6 @@ func (c *Command) Run(args []string) int {
|
|||
config.Ports.SerfLan, config.Ports.SerfWan))
|
||||
c.UI.Info(fmt.Sprintf("Gossip encrypt: %v, RPC-TLS: %v, TLS-Incoming: %v",
|
||||
gossipEncrypted, config.VerifyOutgoing, config.VerifyIncoming))
|
||||
c.UI.Info(fmt.Sprintf(" Atlas: %s", atlas))
|
||||
|
||||
// Enable log streaming
|
||||
c.UI.Info("")
|
||||
|
@ -1064,66 +1050,9 @@ func (c *Command) handleReload(config *Config) (*Config, error) {
|
|||
}(wp)
|
||||
}
|
||||
|
||||
// Reload SCADA client if we have a change
|
||||
if newConf.AtlasInfrastructure != config.AtlasInfrastructure ||
|
||||
newConf.AtlasToken != config.AtlasToken ||
|
||||
newConf.AtlasEndpoint != config.AtlasEndpoint {
|
||||
if err := c.setupScadaConn(newConf); err != nil {
|
||||
errs = multierror.Append(errs, fmt.Errorf("Failed reloading SCADA client: %s", err))
|
||||
return nil, errs
|
||||
}
|
||||
}
|
||||
|
||||
return newConf, errs
|
||||
}
|
||||
|
||||
// startScadaClient is used to start a new SCADA provider and listener,
|
||||
// replacing any existing listeners.
|
||||
func (c *Command) setupScadaConn(config *Config) error {
|
||||
// Shut down existing SCADA listeners
|
||||
if c.scadaProvider != nil {
|
||||
c.scadaProvider.Shutdown()
|
||||
}
|
||||
if c.scadaHTTP != nil {
|
||||
c.scadaHTTP.Shutdown()
|
||||
}
|
||||
|
||||
// No-op if we don't have an infrastructure
|
||||
if config.AtlasInfrastructure == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.UI.Error("WARNING: The hosted version of Consul Enterprise will be deprecated " +
|
||||
"on March 7th, 2017. For details, see " +
|
||||
"https://atlas.hashicorp.com/help/consul/alternatives")
|
||||
|
||||
scadaConfig := &scada.Config{
|
||||
Service: "consul",
|
||||
Version: fmt.Sprintf("%s%s", config.Version, config.VersionPrerelease),
|
||||
ResourceType: "infrastructures",
|
||||
Meta: map[string]string{
|
||||
"auto-join": strconv.FormatBool(config.AtlasJoin),
|
||||
"datacenter": config.Datacenter,
|
||||
"server": strconv.FormatBool(config.Server),
|
||||
},
|
||||
Atlas: scada.AtlasConfig{
|
||||
Endpoint: config.AtlasEndpoint,
|
||||
Infrastructure: config.AtlasInfrastructure,
|
||||
Token: config.AtlasToken,
|
||||
},
|
||||
}
|
||||
|
||||
// Create the new provider and listener
|
||||
c.UI.Output("Connecting to Atlas: " + config.AtlasInfrastructure)
|
||||
provider, list, err := scada.NewHTTPProvider(scadaConfig, c.logOutput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.scadaProvider = provider
|
||||
c.scadaHTTP = newScadaHTTP(c.agent, list)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Command) Synopsis() string {
|
||||
return "Runs a Consul agent"
|
||||
}
|
||||
|
|
|
@ -409,50 +409,6 @@ func TestDiscoverGCEHosts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSetupScadaConn(t *testing.T) {
|
||||
// Create a config and assign an infra name
|
||||
conf1 := nextConfig()
|
||||
conf1.AtlasInfrastructure = "hashicorp/test1"
|
||||
conf1.AtlasToken = "abc"
|
||||
|
||||
dir, agent := makeAgent(t, conf1)
|
||||
defer os.RemoveAll(dir)
|
||||
defer agent.Shutdown()
|
||||
|
||||
cmd := &Command{
|
||||
ShutdownCh: make(chan struct{}),
|
||||
Command: baseCommand(new(cli.MockUi)),
|
||||
agent: agent,
|
||||
}
|
||||
|
||||
// First start creates the scada conn
|
||||
if err := cmd.setupScadaConn(conf1); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
http1 := cmd.scadaHTTP
|
||||
provider1 := cmd.scadaProvider
|
||||
|
||||
// Performing setup again tears down original and replaces
|
||||
// with a new SCADA client.
|
||||
conf2 := nextConfig()
|
||||
conf2.AtlasInfrastructure = "hashicorp/test2"
|
||||
conf2.AtlasToken = "123"
|
||||
if err := cmd.setupScadaConn(conf2); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if cmd.scadaHTTP == http1 || cmd.scadaProvider == provider1 {
|
||||
t.Fatalf("should change: %#v %#v", cmd.scadaHTTP, cmd.scadaProvider)
|
||||
}
|
||||
|
||||
// Original provider and listener must be closed
|
||||
if !provider1.IsShutdown() {
|
||||
t.Fatalf("should be shutdown")
|
||||
}
|
||||
if _, err := http1.listener.Accept(); !strings.Contains(err.Error(), "closed") {
|
||||
t.Fatalf("should be closed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProtectDataDir(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "consul")
|
||||
if err != nil {
|
||||
|
|
|
@ -681,27 +681,6 @@ type Config struct {
|
|||
// HTTPAPIResponseHeaders are used to add HTTP header response fields to the HTTP API responses.
|
||||
HTTPAPIResponseHeaders map[string]string `mapstructure:"http_api_response_headers"`
|
||||
|
||||
// AtlasInfrastructure is the name of the infrastructure we belong to. e.g. hashicorp/stage
|
||||
AtlasInfrastructure string `mapstructure:"atlas_infrastructure"`
|
||||
|
||||
// AtlasToken is our authentication token from Atlas
|
||||
AtlasToken string `mapstructure:"atlas_token" json:"-"`
|
||||
|
||||
// AtlasACLToken is applied to inbound requests if no other token
|
||||
// is provided. This takes higher precedence than the ACLToken.
|
||||
// Without this, the ACLToken is used. If that is not specified either,
|
||||
// then the 'anonymous' token is used. This can be set to 'anonymous'
|
||||
// to reduce the Atlas privileges to below that of the ACLToken.
|
||||
AtlasACLToken string `mapstructure:"atlas_acl_token" json:"-"`
|
||||
|
||||
// AtlasJoin controls if Atlas will attempt to auto-join the node
|
||||
// to it's cluster. Requires Atlas integration.
|
||||
AtlasJoin bool `mapstructure:"atlas_join"`
|
||||
|
||||
// AtlasEndpoint is the SCADA endpoint used for Atlas integration. If
|
||||
// empty, the defaults from the provider are used.
|
||||
AtlasEndpoint string `mapstructure:"atlas_endpoint"`
|
||||
|
||||
// AEInterval controls the anti-entropy interval. This is how often
|
||||
// the agent attempts to reconcile its local state with the server's
|
||||
// representation of our state. Defaults to every 60s.
|
||||
|
@ -749,6 +728,14 @@ type Config struct {
|
|||
// Minimum Session TTL
|
||||
SessionTTLMin time.Duration `mapstructure:"-"`
|
||||
SessionTTLMinRaw string `mapstructure:"session_ttl_min"`
|
||||
|
||||
// deprecated fields
|
||||
// keep them exported since otherwise the error messages don't show up
|
||||
DeprecatedAtlasInfrastructure string `mapstructure:"atlas_infrastructure" json:"-"`
|
||||
DeprecatedAtlasToken string `mapstructure:"atlas_token" json:"-"`
|
||||
DeprecatedAtlasACLToken string `mapstructure:"atlas_acl_token" json:"-"`
|
||||
DeprecatedAtlasJoin bool `mapstructure:"atlas_join" json:"-"`
|
||||
DeprecatedAtlasEndpoint string `mapstructure:"atlas_endpoint" json:"-"`
|
||||
}
|
||||
|
||||
// Bool is used to initialize bool pointers in struct literals.
|
||||
|
@ -1072,6 +1059,26 @@ func DecodeConfig(r io.Reader) (*Config, error) {
|
|||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: addresses.rpc is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
if result.DeprecatedAtlasInfrastructure != "" {
|
||||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: atlas_infrastructure is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
if result.DeprecatedAtlasToken != "" {
|
||||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: atlas_token is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
if result.DeprecatedAtlasACLToken != "" {
|
||||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: atlas_acl_token is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
if result.DeprecatedAtlasJoin != false {
|
||||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: atlas_join is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
if result.DeprecatedAtlasEndpoint != "" {
|
||||
fmt.Fprintln(os.Stderr, "==> DEPRECATION: atlas_endpoint is deprecated and "+
|
||||
"is no longer used. Please remove it from your configuration.")
|
||||
}
|
||||
|
||||
// Check unused fields and verify that no bad configuration options were
|
||||
// passed to Consul. There are a few additional fields which don't directly
|
||||
|
@ -1828,21 +1835,6 @@ func MergeConfig(a, b *Config) *Config {
|
|||
if b.UnixSockets.Perms != "" {
|
||||
result.UnixSockets.Perms = b.UnixSockets.Perms
|
||||
}
|
||||
if b.AtlasInfrastructure != "" {
|
||||
result.AtlasInfrastructure = b.AtlasInfrastructure
|
||||
}
|
||||
if b.AtlasToken != "" {
|
||||
result.AtlasToken = b.AtlasToken
|
||||
}
|
||||
if b.AtlasACLToken != "" {
|
||||
result.AtlasACLToken = b.AtlasACLToken
|
||||
}
|
||||
if b.AtlasJoin {
|
||||
result.AtlasJoin = true
|
||||
}
|
||||
if b.AtlasEndpoint != "" {
|
||||
result.AtlasEndpoint = b.AtlasEndpoint
|
||||
}
|
||||
if b.DisableCoordinates {
|
||||
result.DisableCoordinates = true
|
||||
}
|
||||
|
|
|
@ -1022,7 +1022,7 @@ func TestDecodeConfig(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
|
||||
// Atlas configs
|
||||
// Check deprecations
|
||||
input = `{
|
||||
"atlas_infrastructure": "hashicorp/prod",
|
||||
"atlas_token": "abcdefg",
|
||||
|
@ -1030,27 +1030,11 @@ func TestDecodeConfig(t *testing.T) {
|
|||
"atlas_join": true,
|
||||
"atlas_endpoint": "foo.bar:1111"
|
||||
}`
|
||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
_, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if config.AtlasInfrastructure != "hashicorp/prod" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.AtlasToken != "abcdefg" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.AtlasACLToken != "123456789" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if !config.AtlasJoin {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.AtlasEndpoint != "foo.bar:1111" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
|
||||
// Coordinate disable
|
||||
input = `{"disable_coordinates": true}`
|
||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
|
@ -1779,10 +1763,6 @@ func TestMergeConfig(t *testing.T) {
|
|||
Perms: "0700",
|
||||
},
|
||||
},
|
||||
AtlasInfrastructure: "hashicorp/prod",
|
||||
AtlasToken: "123456789",
|
||||
AtlasACLToken: "abcdefgh",
|
||||
AtlasJoin: true,
|
||||
RetryJoinEC2: RetryJoinEC2{
|
||||
Region: "us-east-2",
|
||||
TagKey: "Key2",
|
||||
|
|
|
@ -21,14 +21,6 @@ import (
|
|||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
var (
|
||||
// scadaHTTPAddr is the address associated with the
|
||||
// HTTPServer. When populating an ACL token for a request,
|
||||
// this is checked to switch between the ACLToken and
|
||||
// AtlasACLToken
|
||||
scadaHTTPAddr = "SCADA"
|
||||
)
|
||||
|
||||
// HTTPServer is used to wrap an Agent and expose various API's
|
||||
// in a RESTful manner
|
||||
type HTTPServer struct {
|
||||
|
@ -155,27 +147,6 @@ func NewHTTPServers(agent *Agent, config *Config, logOutput io.Writer) ([]*HTTPS
|
|||
return servers, nil
|
||||
}
|
||||
|
||||
// newScadaHTTP creates a new HTTP server wrapping the SCADA
|
||||
// listener such that HTTP calls can be sent from the brokers.
|
||||
func newScadaHTTP(agent *Agent, list net.Listener) *HTTPServer {
|
||||
// Create the mux
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Create the server
|
||||
srv := &HTTPServer{
|
||||
agent: agent,
|
||||
mux: mux,
|
||||
listener: list,
|
||||
logger: agent.logger,
|
||||
addr: scadaHTTPAddr,
|
||||
}
|
||||
srv.registerHandlers(false) // Never allow debug for SCADA
|
||||
|
||||
// Start the server
|
||||
go http.Serve(list, mux)
|
||||
return srv
|
||||
}
|
||||
|
||||
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||||
// connections. It's used by NewHttpServer so
|
||||
// dead TCP connections eventually go away.
|
||||
|
@ -567,12 +538,6 @@ func (s *HTTPServer) parseToken(req *http.Request, token *string) {
|
|||
return
|
||||
}
|
||||
|
||||
// Set the AtlasACLToken if SCADA
|
||||
if s.addr == scadaHTTPAddr && s.agent.config.AtlasACLToken != "" {
|
||||
*token = s.agent.config.AtlasACLToken
|
||||
return
|
||||
}
|
||||
|
||||
// Set the default ACLToken
|
||||
*token = s.agent.config.ACLToken
|
||||
}
|
||||
|
|
|
@ -558,27 +558,6 @@ func TestACLResolution(t *testing.T) {
|
|||
t.Fatalf("bad: %s", token)
|
||||
}
|
||||
|
||||
// Check when AtlasACLToken set, wrong server
|
||||
srv.agent.config.AtlasACLToken = "atlas"
|
||||
srv.parseToken(req, &token)
|
||||
if token != "agent" {
|
||||
t.Fatalf("bad: %s", token)
|
||||
}
|
||||
|
||||
// Check when AtlasACLToken set, correct server
|
||||
srv.addr = scadaHTTPAddr
|
||||
srv.parseToken(req, &token)
|
||||
if token != "atlas" {
|
||||
t.Fatalf("bad: %s", token)
|
||||
}
|
||||
|
||||
// Check when AtlasACLToken not, correct server
|
||||
srv.agent.config.AtlasACLToken = ""
|
||||
srv.parseToken(req, &token)
|
||||
if token != "agent" {
|
||||
t.Fatalf("bad: %s", token)
|
||||
}
|
||||
|
||||
// Explicit token has highest precedence
|
||||
srv.parseToken(reqToken, &token)
|
||||
if token != "foo" {
|
||||
|
@ -599,39 +578,6 @@ func TestACLResolution(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestScadaHTTP(t *testing.T) {
|
||||
// Create the agent
|
||||
dir, agent := makeAgent(t, nextConfig())
|
||||
defer os.RemoveAll(dir)
|
||||
defer agent.Shutdown()
|
||||
|
||||
// Create a generic listener
|
||||
list, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer list.Close()
|
||||
|
||||
// Create the SCADA HTTP server
|
||||
scadaHTTP := newScadaHTTP(agent, list)
|
||||
|
||||
// Returned server uses the listener and scada addr
|
||||
if scadaHTTP.listener != list {
|
||||
t.Fatalf("bad listener: %#v", scadaHTTP)
|
||||
}
|
||||
if scadaHTTP.addr != scadaHTTPAddr {
|
||||
t.Fatalf("expected %v, got: %v", scadaHTTP.addr, scadaHTTPAddr)
|
||||
}
|
||||
|
||||
// Check that debug endpoints were not enabled. This will cause
|
||||
// the serve mux to panic if the routes are already handled.
|
||||
mockFn := func(w http.ResponseWriter, r *http.Request) {}
|
||||
scadaHTTP.mux.HandleFunc("/debug/pprof/", mockFn)
|
||||
scadaHTTP.mux.HandleFunc("/debug/pprof/cmdline", mockFn)
|
||||
scadaHTTP.mux.HandleFunc("/debug/pprof/profile", mockFn)
|
||||
scadaHTTP.mux.HandleFunc("/debug/pprof/symbol", mockFn)
|
||||
}
|
||||
|
||||
func TestEnableWebUI(t *testing.T) {
|
||||
httpTestWithConfig(t, func(s *HTTPServer) {
|
||||
req, _ := http.NewRequest("GET", "/ui/", nil)
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
package scada
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
sc "github.com/hashicorp/scada-client"
|
||||
)
|
||||
|
||||
// Provider wraps scada-client.Provider to allow most applications to only pull
|
||||
// in this package
|
||||
type Provider struct {
|
||||
*sc.Provider
|
||||
}
|
||||
|
||||
type AtlasConfig struct {
|
||||
// Endpoint is the SCADA endpoint used for Atlas integration. If empty, the
|
||||
// defaults from the provider are used.
|
||||
Endpoint string `mapstructure:"endpoint"`
|
||||
|
||||
// The name of the infrastructure we belong to, e.g. "hashicorp/prod"
|
||||
Infrastructure string `mapstructure:"infrastructure"`
|
||||
|
||||
// The Atlas authentication token
|
||||
Token string `mapstructure:"token" json:"-"`
|
||||
}
|
||||
|
||||
// Config holds the high-level information used to instantiate a SCADA provider
|
||||
// and listener
|
||||
type Config struct {
|
||||
// The service name to use
|
||||
Service string
|
||||
|
||||
// The version of the service
|
||||
Version string
|
||||
|
||||
// The type of resource we represent
|
||||
ResourceType string
|
||||
|
||||
// Metadata to send to along with the service information
|
||||
Meta map[string]string
|
||||
|
||||
// If set, TLS certificate verification will be skipped. The value of the
|
||||
// SCADA_INSECURE environment variable will be considered if this is false.
|
||||
// If using SCADA_INSECURE, any non-empty value will trigger insecure mode.
|
||||
Insecure bool
|
||||
|
||||
// Holds Atlas configuration
|
||||
Atlas AtlasConfig
|
||||
}
|
||||
|
||||
// ProviderService returns the service information for the provider
|
||||
func providerService(c *Config) *sc.ProviderService {
|
||||
ret := &sc.ProviderService{
|
||||
Service: c.Service,
|
||||
ServiceVersion: c.Version,
|
||||
Capabilities: map[string]int{},
|
||||
Meta: c.Meta,
|
||||
ResourceType: c.ResourceType,
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// providerConfig returns the configuration for the SCADA provider
|
||||
func providerConfig(c *Config) *sc.ProviderConfig {
|
||||
ret := &sc.ProviderConfig{
|
||||
Service: providerService(c),
|
||||
Handlers: map[string]sc.CapabilityProvider{},
|
||||
Endpoint: c.Atlas.Endpoint,
|
||||
ResourceGroup: c.Atlas.Infrastructure,
|
||||
Token: c.Atlas.Token,
|
||||
}
|
||||
|
||||
// SCADA_INSECURE env variable is used for testing to disable TLS
|
||||
// certificate verification.
|
||||
insecure := c.Insecure
|
||||
if !insecure {
|
||||
if os.Getenv("SCADA_INSECURE") != "" {
|
||||
insecure = true
|
||||
}
|
||||
}
|
||||
if insecure {
|
||||
ret.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// NewProvider creates a new SCADA provider using the given configuration.
|
||||
// Requests for the HTTP capability are passed off to the listener that is
|
||||
// returned.
|
||||
func NewHTTPProvider(c *Config, logOutput io.Writer) (*Provider, net.Listener, error) {
|
||||
// Get the configuration of the provider
|
||||
config := providerConfig(c)
|
||||
config.LogOutput = logOutput
|
||||
|
||||
// Set the HTTP capability
|
||||
config.Service.Capabilities["http"] = 1
|
||||
|
||||
// Create an HTTP listener and handler
|
||||
list := newScadaListener(c.Atlas.Infrastructure)
|
||||
config.Handlers["http"] = func(capability string, meta map[string]string,
|
||||
conn io.ReadWriteCloser) error {
|
||||
return list.PushRWC(conn)
|
||||
}
|
||||
|
||||
// Create the provider
|
||||
provider, err := sc.NewProvider(config)
|
||||
if err != nil {
|
||||
list.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &Provider{provider}, list, nil
|
||||
}
|
||||
|
||||
// scadaListener is used to return a net.Listener for
|
||||
// incoming SCADA connections
|
||||
type scadaListener struct {
|
||||
addr *scadaAddr
|
||||
pending chan net.Conn
|
||||
|
||||
closed bool
|
||||
closedCh chan struct{}
|
||||
l sync.Mutex
|
||||
}
|
||||
|
||||
// newScadaListener returns a new listener
|
||||
func newScadaListener(infra string) *scadaListener {
|
||||
l := &scadaListener{
|
||||
addr: &scadaAddr{infra},
|
||||
pending: make(chan net.Conn),
|
||||
closedCh: make(chan struct{}),
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// PushRWC is used to push a io.ReadWriteCloser as a net.Conn
|
||||
func (s *scadaListener) PushRWC(conn io.ReadWriteCloser) error {
|
||||
// Check if this already implements net.Conn
|
||||
if nc, ok := conn.(net.Conn); ok {
|
||||
return s.Push(nc)
|
||||
}
|
||||
|
||||
// Wrap to implement the interface
|
||||
wrapped := &scadaRWC{conn, s.addr}
|
||||
return s.Push(wrapped)
|
||||
}
|
||||
|
||||
// Push is used to add a connection to the queu
|
||||
func (s *scadaListener) Push(conn net.Conn) error {
|
||||
select {
|
||||
case s.pending <- conn:
|
||||
return nil
|
||||
case <-time.After(time.Second):
|
||||
return fmt.Errorf("accept timed out")
|
||||
case <-s.closedCh:
|
||||
return fmt.Errorf("scada listener closed")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scadaListener) Accept() (net.Conn, error) {
|
||||
select {
|
||||
case conn := <-s.pending:
|
||||
return conn, nil
|
||||
case <-s.closedCh:
|
||||
return nil, fmt.Errorf("scada listener closed")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scadaListener) Close() error {
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
if s.closed {
|
||||
return nil
|
||||
}
|
||||
s.closed = true
|
||||
close(s.closedCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scadaListener) Addr() net.Addr {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
// scadaAddr is used to return a net.Addr for SCADA
|
||||
type scadaAddr struct {
|
||||
infra string
|
||||
}
|
||||
|
||||
func (s *scadaAddr) Network() string {
|
||||
return "SCADA"
|
||||
}
|
||||
|
||||
func (s *scadaAddr) String() string {
|
||||
return fmt.Sprintf("SCADA::Atlas::%s", s.infra)
|
||||
}
|
||||
|
||||
type scadaRWC struct {
|
||||
io.ReadWriteCloser
|
||||
addr *scadaAddr
|
||||
}
|
||||
|
||||
func (s *scadaRWC) LocalAddr() net.Addr {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
func (s *scadaRWC) RemoteAddr() net.Addr {
|
||||
return s.addr
|
||||
}
|
||||
|
||||
func (s *scadaRWC) SetDeadline(t time.Time) error {
|
||||
return errors.New("SCADA.Conn does not support deadlines")
|
||||
}
|
||||
|
||||
func (s *scadaRWC) SetReadDeadline(t time.Time) error {
|
||||
return errors.New("SCADA.Conn does not support deadlines")
|
||||
}
|
||||
|
||||
func (s *scadaRWC) SetWriteDeadline(t time.Time) error {
|
||||
return errors.New("SCADA.Conn does not support deadlines")
|
||||
}
|
|
@ -631,12 +631,6 @@
|
|||
"revision": "6e896784f66f82cdc6f17e00052db91699dc277d",
|
||||
"revisionTime": "2016-06-01T22:40:23Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "fv3nX1vDZViW0tA7Aa5Va2lBUtM=",
|
||||
"path": "github.com/hashicorp/scada-client/scada",
|
||||
"revision": "6e896784f66f82cdc6f17e00052db91699dc277d",
|
||||
"revisionTime": "2016-06-01T22:40:23Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=",
|
||||
"comment": "v0.7.0-66-g6c4672d",
|
||||
|
|
Loading…
Reference in New Issue