agent: drop atlas/scada code

This commit is contained in:
Frank Schroeder 2017-05-10 17:45:17 +02:00 committed by Frank Schröder
parent 091bea4922
commit e13f3446ac
8 changed files with 63 additions and 532 deletions

View file

@ -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"
}

View file

@ -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 {

View file

@ -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
}

View file

@ -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",

View file

@ -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
}

View file

@ -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)

View file

@ -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")
}

6
vendor/vendor.json vendored
View file

@ -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",