github.com/superfly/nomad@v0.10.5-fly/command/agent/agent_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	cstructs "github.com/hashicorp/nomad/client/structs"
    12  	"github.com/hashicorp/nomad/helper"
    13  	"github.com/hashicorp/nomad/helper/testlog"
    14  	"github.com/hashicorp/nomad/nomad/structs"
    15  	"github.com/hashicorp/nomad/nomad/structs/config"
    16  	sconfig "github.com/hashicorp/nomad/nomad/structs/config"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func tmpDir(t testing.TB) string {
    22  	dir, err := ioutil.TempDir("", "nomad")
    23  	if err != nil {
    24  		t.Fatalf("err: %v", err)
    25  	}
    26  	return dir
    27  }
    28  
    29  func TestAgent_RPC_Ping(t *testing.T) {
    30  	t.Parallel()
    31  	agent := NewTestAgent(t, t.Name(), nil)
    32  	defer agent.Shutdown()
    33  
    34  	var out struct{}
    35  	if err := agent.RPC("Status.Ping", struct{}{}, &out); err != nil {
    36  		t.Fatalf("err: %v", err)
    37  	}
    38  }
    39  
    40  func TestAgent_ServerConfig(t *testing.T) {
    41  	t.Parallel()
    42  	conf := DefaultConfig()
    43  	conf.DevMode = true // allow localhost for advertise addrs
    44  	conf.Server.Enabled = true
    45  	a := &Agent{config: conf}
    46  
    47  	conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
    48  	conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
    49  	conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
    50  	conf.ACL.Enabled = true
    51  
    52  	// Parses the advertise addrs correctly
    53  	if err := conf.normalizeAddrs(); err != nil {
    54  		t.Fatalf("error normalizing config: %v", err)
    55  	}
    56  	out, err := a.serverConfig()
    57  	require.NoError(t, err)
    58  
    59  	serfAddr := out.SerfConfig.MemberlistConfig.AdvertiseAddr
    60  	require.Equal(t, "127.0.0.1", serfAddr)
    61  
    62  	serfPort := out.SerfConfig.MemberlistConfig.AdvertisePort
    63  	require.Equal(t, 4000, serfPort)
    64  
    65  	require.Equal(t, "global", out.AuthoritativeRegion)
    66  	require.True(t, out.ACLEnabled)
    67  
    68  	// Assert addresses weren't changed
    69  	require.Equal(t, "127.0.0.1:4001", conf.AdvertiseAddrs.RPC)
    70  	require.Equal(t, "10.10.11.1:4005", conf.AdvertiseAddrs.HTTP)
    71  	require.Equal(t, "0.0.0.0", conf.Addresses.RPC)
    72  
    73  	// Sets up the ports properly
    74  	conf.Addresses.RPC = ""
    75  	conf.Addresses.Serf = ""
    76  	conf.Ports.RPC = 4003
    77  	conf.Ports.Serf = 4004
    78  
    79  	require.NoError(t, conf.normalizeAddrs())
    80  
    81  	out, err = a.serverConfig()
    82  	require.NoError(t, err)
    83  	require.Equal(t, 4003, out.RPCAddr.Port)
    84  	require.Equal(t, 4004, out.SerfConfig.MemberlistConfig.BindPort)
    85  
    86  	// Prefers advertise over bind addr
    87  	conf.BindAddr = "127.0.0.3"
    88  	conf.Addresses.HTTP = "127.0.0.2"
    89  	conf.Addresses.RPC = "127.0.0.2"
    90  	conf.Addresses.Serf = "127.0.0.2"
    91  	conf.AdvertiseAddrs.HTTP = "10.0.0.10"
    92  	conf.AdvertiseAddrs.RPC = ""
    93  	conf.AdvertiseAddrs.Serf = "10.0.0.12:4004"
    94  
    95  	require.NoError(t, conf.normalizeAddrs())
    96  
    97  	out, err = a.serverConfig()
    98  	require.Equal(t, "127.0.0.2", out.RPCAddr.IP.String())
    99  	require.Equal(t, 4003, out.RPCAddr.Port)
   100  	require.Equal(t, "127.0.0.2", out.SerfConfig.MemberlistConfig.BindAddr)
   101  	require.Equal(t, 4004, out.SerfConfig.MemberlistConfig.BindPort)
   102  	require.Equal(t, "127.0.0.2", conf.Addresses.HTTP)
   103  	require.Equal(t, "127.0.0.2", conf.Addresses.RPC)
   104  	require.Equal(t, "127.0.0.2", conf.Addresses.Serf)
   105  	require.Equal(t, "127.0.0.2:4646", conf.normalizedAddrs.HTTP)
   106  	require.Equal(t, "127.0.0.2:4003", conf.normalizedAddrs.RPC)
   107  	require.Equal(t, "127.0.0.2:4004", conf.normalizedAddrs.Serf)
   108  	require.Equal(t, "10.0.0.10:4646", conf.AdvertiseAddrs.HTTP)
   109  	require.Equal(t, "127.0.0.2:4003", conf.AdvertiseAddrs.RPC)
   110  	require.Equal(t, "10.0.0.12:4004", conf.AdvertiseAddrs.Serf)
   111  
   112  	conf.Server.NodeGCThreshold = "42g"
   113  	require.NoError(t, conf.normalizeAddrs())
   114  
   115  	_, err = a.serverConfig()
   116  	if err == nil || !strings.Contains(err.Error(), "unknown unit") {
   117  		t.Fatalf("expected unknown unit error, got: %#v", err)
   118  	}
   119  
   120  	conf.Server.NodeGCThreshold = "10s"
   121  	require.NoError(t, conf.normalizeAddrs())
   122  	out, err = a.serverConfig()
   123  	require.NoError(t, err)
   124  	require.Equal(t, 10*time.Second, out.NodeGCThreshold)
   125  
   126  	conf.Server.HeartbeatGrace = 37 * time.Second
   127  	out, err = a.serverConfig()
   128  	require.NoError(t, err)
   129  	require.Equal(t, 37*time.Second, out.HeartbeatGrace)
   130  
   131  	conf.Server.MinHeartbeatTTL = 37 * time.Second
   132  	out, err = a.serverConfig()
   133  	require.NoError(t, err)
   134  	require.Equal(t, 37*time.Second, out.MinHeartbeatTTL)
   135  
   136  	conf.Server.MaxHeartbeatsPerSecond = 11.0
   137  	out, err = a.serverConfig()
   138  	require.NoError(t, err)
   139  	require.Equal(t, float64(11.0), out.MaxHeartbeatsPerSecond)
   140  
   141  	// Defaults to the global bind addr
   142  	conf.Addresses.RPC = ""
   143  	conf.Addresses.Serf = ""
   144  	conf.Addresses.HTTP = ""
   145  	conf.AdvertiseAddrs.RPC = ""
   146  	conf.AdvertiseAddrs.HTTP = ""
   147  	conf.AdvertiseAddrs.Serf = ""
   148  	conf.Ports.HTTP = 4646
   149  	conf.Ports.RPC = 4647
   150  	conf.Ports.Serf = 4648
   151  	require.NoError(t, conf.normalizeAddrs())
   152  
   153  	out, err = a.serverConfig()
   154  	require.NoError(t, err)
   155  
   156  	require.Equal(t, "127.0.0.3", out.RPCAddr.IP.String())
   157  	require.Equal(t, "127.0.0.3", out.SerfConfig.MemberlistConfig.BindAddr)
   158  	require.Equal(t, "127.0.0.3", conf.Addresses.HTTP)
   159  	require.Equal(t, "127.0.0.3", conf.Addresses.RPC)
   160  	require.Equal(t, "127.0.0.3", conf.Addresses.Serf)
   161  	require.Equal(t, "127.0.0.3:4646", conf.normalizedAddrs.HTTP)
   162  	require.Equal(t, "127.0.0.3:4647", conf.normalizedAddrs.RPC)
   163  	require.Equal(t, "127.0.0.3:4648", conf.normalizedAddrs.Serf)
   164  
   165  	// Properly handles the bootstrap flags
   166  	conf.Server.BootstrapExpect = 1
   167  	out, err = a.serverConfig()
   168  	require.NoError(t, err)
   169  	require.True(t, out.Bootstrap)
   170  	require.Equal(t, int32(0), out.BootstrapExpect)
   171  
   172  	conf.Server.BootstrapExpect = 3
   173  	out, err = a.serverConfig()
   174  	require.NoError(t, err)
   175  	require.False(t, out.Bootstrap)
   176  	require.Equal(t, int32(3), out.BootstrapExpect)
   177  }
   178  
   179  func TestAgent_ServerConfig_SchedulerFlags(t *testing.T) {
   180  	cases := []struct {
   181  		name     string
   182  		input    *structs.SchedulerConfiguration
   183  		expected structs.SchedulerConfiguration
   184  	}{
   185  		{
   186  			"default case",
   187  			nil,
   188  			structs.SchedulerConfiguration{
   189  				PreemptionConfig: structs.PreemptionConfig{
   190  					SystemSchedulerEnabled: true,
   191  				},
   192  			},
   193  		},
   194  		{
   195  			"empty value: preemption is disabled",
   196  			&structs.SchedulerConfiguration{},
   197  			structs.SchedulerConfiguration{
   198  				PreemptionConfig: structs.PreemptionConfig{
   199  					SystemSchedulerEnabled: false,
   200  				},
   201  			},
   202  		},
   203  		{
   204  			"all explicitly set",
   205  			&structs.SchedulerConfiguration{
   206  				PreemptionConfig: structs.PreemptionConfig{
   207  					SystemSchedulerEnabled:  true,
   208  					BatchSchedulerEnabled:   true,
   209  					ServiceSchedulerEnabled: true,
   210  				},
   211  			},
   212  			structs.SchedulerConfiguration{
   213  				PreemptionConfig: structs.PreemptionConfig{
   214  					SystemSchedulerEnabled:  true,
   215  					BatchSchedulerEnabled:   true,
   216  					ServiceSchedulerEnabled: true,
   217  				},
   218  			},
   219  		},
   220  	}
   221  
   222  	for _, c := range cases {
   223  		t.Run(c.name, func(t *testing.T) {
   224  			conf := DefaultConfig()
   225  			conf.Server.DefaultSchedulerConfig = c.input
   226  
   227  			a := &Agent{config: conf}
   228  			conf.AdvertiseAddrs.Serf = "127.0.0.1:4000"
   229  			conf.AdvertiseAddrs.RPC = "127.0.0.1:4001"
   230  			conf.AdvertiseAddrs.HTTP = "10.10.11.1:4005"
   231  			conf.ACL.Enabled = true
   232  			require.NoError(t, conf.normalizeAddrs())
   233  
   234  			out, err := a.serverConfig()
   235  			require.NoError(t, err)
   236  			require.Equal(t, c.expected, out.DefaultSchedulerConfig)
   237  		})
   238  	}
   239  }
   240  
   241  // TestAgent_ServerConfig_Limits_Errors asserts invalid Limits configurations
   242  // cause errors. This is the server-only (RPC) counterpart to
   243  // TestHTTPServer_Limits_Error.
   244  func TestAgent_ServerConfig_Limits_Error(t *testing.T) {
   245  	t.Parallel()
   246  
   247  	cases := []struct {
   248  		name        string
   249  		expectedErr string
   250  		limits      sconfig.Limits
   251  	}{
   252  		{
   253  			name:        "Negative Timeout",
   254  			expectedErr: "rpc_handshake_timeout must be >= 0",
   255  			limits: sconfig.Limits{
   256  				RPCHandshakeTimeout:  "-5s",
   257  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   258  			},
   259  		},
   260  		{
   261  			name:        "Invalid Timeout",
   262  			expectedErr: "error parsing rpc_handshake_timeout",
   263  			limits: sconfig.Limits{
   264  				RPCHandshakeTimeout:  "s",
   265  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   266  			},
   267  		},
   268  		{
   269  			name:        "Missing Timeout",
   270  			expectedErr: "error parsing rpc_handshake_timeout",
   271  			limits: sconfig.Limits{
   272  				RPCHandshakeTimeout:  "",
   273  				RPCMaxConnsPerClient: helper.IntToPtr(100),
   274  			},
   275  		},
   276  		{
   277  			name:        "Negative Connection Limit",
   278  			expectedErr: "rpc_max_conns_per_client must be > 25; found: -100",
   279  			limits: sconfig.Limits{
   280  				RPCHandshakeTimeout:  "5s",
   281  				RPCMaxConnsPerClient: helper.IntToPtr(-100),
   282  			},
   283  		},
   284  		{
   285  			name:        "Low Connection Limit",
   286  			expectedErr: "rpc_max_conns_per_client must be > 25; found: 20",
   287  			limits: sconfig.Limits{
   288  				RPCHandshakeTimeout:  "5s",
   289  				RPCMaxConnsPerClient: helper.IntToPtr(sconfig.LimitsNonStreamingConnsPerClient),
   290  			},
   291  		},
   292  	}
   293  
   294  	for i := range cases {
   295  		tc := cases[i]
   296  		t.Run(tc.name, func(t *testing.T) {
   297  			conf := DevConfig(nil)
   298  			require.NoError(t, conf.normalizeAddrs())
   299  
   300  			conf.Limits = tc.limits
   301  			serverConf, err := convertServerConfig(conf)
   302  			assert.Nil(t, serverConf)
   303  			require.Contains(t, err.Error(), tc.expectedErr)
   304  		})
   305  	}
   306  }
   307  
   308  // TestAgent_ServerConfig_Limits_OK asserts valid Limits configurations do not
   309  // cause errors. This is the server-only (RPC) counterpart to
   310  // TestHTTPServer_Limits_OK.
   311  func TestAgent_ServerConfig_Limits_OK(t *testing.T) {
   312  	t.Parallel()
   313  
   314  	cases := []struct {
   315  		name   string
   316  		limits sconfig.Limits
   317  	}{
   318  		{
   319  			name:   "Default",
   320  			limits: config.DefaultLimits(),
   321  		},
   322  		{
   323  			name: "Zero+nil is valid to disable",
   324  			limits: sconfig.Limits{
   325  				RPCHandshakeTimeout:  "0",
   326  				RPCMaxConnsPerClient: nil,
   327  			},
   328  		},
   329  		{
   330  			name: "Zeros are valid",
   331  			limits: sconfig.Limits{
   332  				RPCHandshakeTimeout:  "0s",
   333  				RPCMaxConnsPerClient: helper.IntToPtr(0),
   334  			},
   335  		},
   336  		{
   337  			name: "Low limits are valid",
   338  			limits: sconfig.Limits{
   339  				RPCHandshakeTimeout:  "1ms",
   340  				RPCMaxConnsPerClient: helper.IntToPtr(26),
   341  			},
   342  		},
   343  		{
   344  			name: "High limits are valid",
   345  			limits: sconfig.Limits{
   346  				RPCHandshakeTimeout:  "5h",
   347  				RPCMaxConnsPerClient: helper.IntToPtr(100000),
   348  			},
   349  		},
   350  	}
   351  
   352  	for i := range cases {
   353  		tc := cases[i]
   354  		t.Run(tc.name, func(t *testing.T) {
   355  			conf := DevConfig(nil)
   356  			require.NoError(t, conf.normalizeAddrs())
   357  
   358  			conf.Limits = tc.limits
   359  			serverConf, err := convertServerConfig(conf)
   360  			assert.NoError(t, err)
   361  			require.NotNil(t, serverConf)
   362  		})
   363  	}
   364  }
   365  
   366  func TestAgent_ClientConfig(t *testing.T) {
   367  	t.Parallel()
   368  	conf := DefaultConfig()
   369  	conf.Client.Enabled = true
   370  
   371  	// For Clients HTTP and RPC must be set (Serf can be skipped)
   372  	conf.Addresses.HTTP = "169.254.0.1"
   373  	conf.Addresses.RPC = "169.254.0.1"
   374  	conf.Ports.HTTP = 5678
   375  	a := &Agent{config: conf}
   376  
   377  	if err := conf.normalizeAddrs(); err != nil {
   378  		t.Fatalf("error normalizing config: %v", err)
   379  	}
   380  	c, err := a.clientConfig()
   381  	if err != nil {
   382  		t.Fatalf("got err: %v", err)
   383  	}
   384  
   385  	expectedHttpAddr := "169.254.0.1:5678"
   386  	if c.Node.HTTPAddr != expectedHttpAddr {
   387  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   388  	}
   389  
   390  	conf = DefaultConfig()
   391  	conf.DevMode = true
   392  	a = &Agent{config: conf}
   393  	conf.Client.Enabled = true
   394  	conf.Addresses.HTTP = "169.254.0.1"
   395  
   396  	if err := conf.normalizeAddrs(); err != nil {
   397  		t.Fatalf("error normalizing config: %v", err)
   398  	}
   399  	c, err = a.clientConfig()
   400  	if err != nil {
   401  		t.Fatalf("got err: %v", err)
   402  	}
   403  
   404  	expectedHttpAddr = "169.254.0.1:4646"
   405  	if c.Node.HTTPAddr != expectedHttpAddr {
   406  		t.Fatalf("Expected http addr: %v, got: %v", expectedHttpAddr, c.Node.HTTPAddr)
   407  	}
   408  }
   409  
   410  // Clients should inherit telemetry configuration
   411  func TestAgent_Client_TelemetryConfiguration(t *testing.T) {
   412  	assert := assert.New(t)
   413  
   414  	conf := DefaultConfig()
   415  	conf.DevMode = true
   416  	conf.Telemetry.DisableTaggedMetrics = true
   417  	conf.Telemetry.BackwardsCompatibleMetrics = true
   418  
   419  	a := &Agent{config: conf}
   420  
   421  	c, err := a.clientConfig()
   422  	assert.Nil(err)
   423  
   424  	telemetry := conf.Telemetry
   425  
   426  	assert.Equal(c.StatsCollectionInterval, telemetry.collectionInterval)
   427  	assert.Equal(c.PublishNodeMetrics, telemetry.PublishNodeMetrics)
   428  	assert.Equal(c.PublishAllocationMetrics, telemetry.PublishAllocationMetrics)
   429  	assert.Equal(c.DisableTaggedMetrics, telemetry.DisableTaggedMetrics)
   430  	assert.Equal(c.BackwardsCompatibleMetrics, telemetry.BackwardsCompatibleMetrics)
   431  }
   432  
   433  // TestAgent_HTTPCheck asserts Agent.agentHTTPCheck properly alters the HTTP
   434  // API health check depending on configuration.
   435  func TestAgent_HTTPCheck(t *testing.T) {
   436  	t.Parallel()
   437  	logger := testlog.HCLogger(t)
   438  	agent := func() *Agent {
   439  		return &Agent{
   440  			logger: logger,
   441  			config: &Config{
   442  				AdvertiseAddrs:  &AdvertiseAddrs{HTTP: "advertise:4646"},
   443  				normalizedAddrs: &Addresses{HTTP: "normalized:4646"},
   444  				Consul: &sconfig.ConsulConfig{
   445  					ChecksUseAdvertise: helper.BoolToPtr(false),
   446  				},
   447  				TLSConfig: &sconfig.TLSConfig{EnableHTTP: false},
   448  			},
   449  		}
   450  	}
   451  
   452  	t.Run("Plain HTTP Check", func(t *testing.T) {
   453  		a := agent()
   454  		check := a.agentHTTPCheck(false)
   455  		if check == nil {
   456  			t.Fatalf("expected non-nil check")
   457  		}
   458  		if check.Type != "http" {
   459  			t.Errorf("expected http check not: %q", check.Type)
   460  		}
   461  		if expected := "/v1/agent/health?type=client"; check.Path != expected {
   462  			t.Errorf("expected %q path not: %q", expected, check.Path)
   463  		}
   464  		if check.Protocol != "http" {
   465  			t.Errorf("expected http proto not: %q", check.Protocol)
   466  		}
   467  		if expected := a.config.normalizedAddrs.HTTP; check.PortLabel != expected {
   468  			t.Errorf("expected normalized addr not %q", check.PortLabel)
   469  		}
   470  	})
   471  
   472  	t.Run("Plain HTTP + ChecksUseAdvertise", func(t *testing.T) {
   473  		a := agent()
   474  		a.config.Consul.ChecksUseAdvertise = helper.BoolToPtr(true)
   475  		check := a.agentHTTPCheck(false)
   476  		if check == nil {
   477  			t.Fatalf("expected non-nil check")
   478  		}
   479  		if expected := a.config.AdvertiseAddrs.HTTP; check.PortLabel != expected {
   480  			t.Errorf("expected advertise addr not %q", check.PortLabel)
   481  		}
   482  	})
   483  
   484  	t.Run("HTTPS", func(t *testing.T) {
   485  		a := agent()
   486  		a.config.TLSConfig.EnableHTTP = true
   487  
   488  		check := a.agentHTTPCheck(false)
   489  		if check == nil {
   490  			t.Fatalf("expected non-nil check")
   491  		}
   492  		if !check.TLSSkipVerify {
   493  			t.Errorf("expected tls skip verify")
   494  		}
   495  		if check.Protocol != "https" {
   496  			t.Errorf("expected https not: %q", check.Protocol)
   497  		}
   498  	})
   499  
   500  	t.Run("HTTPS + VerifyHTTPSClient", func(t *testing.T) {
   501  		a := agent()
   502  		a.config.TLSConfig.EnableHTTP = true
   503  		a.config.TLSConfig.VerifyHTTPSClient = true
   504  
   505  		if check := a.agentHTTPCheck(false); check != nil {
   506  			t.Fatalf("expected nil check not: %#v", check)
   507  		}
   508  	})
   509  }
   510  
   511  // TestAgent_HTTPCheckPath asserts clients and servers use different endpoints
   512  // for healthchecks.
   513  func TestAgent_HTTPCheckPath(t *testing.T) {
   514  	t.Parallel()
   515  	// Agent.agentHTTPCheck only needs a config and logger
   516  	a := &Agent{
   517  		config: DevConfig(nil),
   518  		logger: testlog.HCLogger(t),
   519  	}
   520  	if err := a.config.normalizeAddrs(); err != nil {
   521  		t.Fatalf("error normalizing config: %v", err)
   522  	}
   523  
   524  	// Assert server check uses /v1/agent/health?type=server
   525  	isServer := true
   526  	check := a.agentHTTPCheck(isServer)
   527  	if expected := "Nomad Server HTTP Check"; check.Name != expected {
   528  		t.Errorf("expected server check name to be %q but found %q", expected, check.Name)
   529  	}
   530  	if expected := "/v1/agent/health?type=server"; check.Path != expected {
   531  		t.Errorf("expected server check path to be %q but found %q", expected, check.Path)
   532  	}
   533  
   534  	// Assert client check uses /v1/agent/health?type=client
   535  	isServer = false
   536  	check = a.agentHTTPCheck(isServer)
   537  	if expected := "Nomad Client HTTP Check"; check.Name != expected {
   538  		t.Errorf("expected client check name to be %q but found %q", expected, check.Name)
   539  	}
   540  	if expected := "/v1/agent/health?type=client"; check.Path != expected {
   541  		t.Errorf("expected client check path to be %q but found %q", expected, check.Path)
   542  	}
   543  }
   544  
   545  // Here we validate that log levels get updated when the configuration is
   546  // reloaded. I can't find a good way to fetch this from the logger itself, so
   547  // we pull it only from the agents configuration struct, not the logger.
   548  func TestAgent_Reload_LogLevel(t *testing.T) {
   549  	t.Parallel()
   550  	assert := assert.New(t)
   551  
   552  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   553  		c.LogLevel = "INFO"
   554  	})
   555  	defer agent.Shutdown()
   556  
   557  	assert.Equal("INFO", agent.GetConfig().LogLevel)
   558  
   559  	newConfig := &Config{
   560  		LogLevel: "TRACE",
   561  	}
   562  
   563  	assert.Nil(agent.Reload(newConfig))
   564  	assert.Equal("TRACE", agent.GetConfig().LogLevel)
   565  }
   566  
   567  // This test asserts that the keyloader embedded in the TLS config is shared
   568  // across the Agent, Server, and Client. This is essential for certificate
   569  // reloading to work.
   570  func TestServer_Reload_TLS_Shared_Keyloader(t *testing.T) {
   571  	t.Parallel()
   572  	assert := assert.New(t)
   573  
   574  	// We will start out with a bad cert and then reload with a good one.
   575  	const (
   576  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   577  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   578  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   579  		foocert2 = "../../helper/tlsutil/testdata/nomad-foo.pem"
   580  		fookey2  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   581  	)
   582  
   583  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   584  		c.TLSConfig = &sconfig.TLSConfig{
   585  			EnableHTTP:           true,
   586  			EnableRPC:            true,
   587  			VerifyServerHostname: true,
   588  			CAFile:               cafile,
   589  			CertFile:             foocert,
   590  			KeyFile:              fookey,
   591  		}
   592  	})
   593  	defer agent.Shutdown()
   594  
   595  	originalKeyloader := agent.Config.TLSConfig.GetKeyLoader()
   596  	originalCert, err := originalKeyloader.GetOutgoingCertificate(nil)
   597  	assert.NotNil(originalKeyloader)
   598  	if assert.Nil(err) {
   599  		assert.NotNil(originalCert)
   600  	}
   601  
   602  	// Switch to the correct certificates and reload
   603  	newConfig := &Config{
   604  		TLSConfig: &sconfig.TLSConfig{
   605  			EnableHTTP:           true,
   606  			EnableRPC:            true,
   607  			VerifyServerHostname: true,
   608  			CAFile:               cafile,
   609  			CertFile:             foocert2,
   610  			KeyFile:              fookey2,
   611  		},
   612  	}
   613  
   614  	assert.Nil(agent.Reload(newConfig))
   615  	assert.Equal(agent.Config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   616  	assert.Equal(agent.Config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   617  	assert.Equal(agent.Config.TLSConfig.GetKeyLoader(), originalKeyloader)
   618  
   619  	// Assert is passed through on the server correctly
   620  	if assert.NotNil(agent.server.GetConfig().TLSConfig) {
   621  		serverKeyloader := agent.server.GetConfig().TLSConfig.GetKeyLoader()
   622  		assert.Equal(serverKeyloader, originalKeyloader)
   623  		newCert, err := serverKeyloader.GetOutgoingCertificate(nil)
   624  		assert.Nil(err)
   625  		assert.NotEqual(originalCert, newCert)
   626  	}
   627  
   628  	// Assert is passed through on the client correctly
   629  	if assert.NotNil(agent.client.GetConfig().TLSConfig) {
   630  		clientKeyloader := agent.client.GetConfig().TLSConfig.GetKeyLoader()
   631  		assert.Equal(clientKeyloader, originalKeyloader)
   632  		newCert, err := clientKeyloader.GetOutgoingCertificate(nil)
   633  		assert.Nil(err)
   634  		assert.NotEqual(originalCert, newCert)
   635  	}
   636  }
   637  
   638  func TestServer_Reload_TLS_Certificate(t *testing.T) {
   639  	t.Parallel()
   640  	assert := assert.New(t)
   641  
   642  	const (
   643  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   644  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   645  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   646  		foocert2 = "../../helper/tlsutil/testdata/nomad-foo.pem"
   647  		fookey2  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   648  	)
   649  
   650  	agentConfig := &Config{
   651  		TLSConfig: &sconfig.TLSConfig{
   652  			EnableHTTP:           true,
   653  			EnableRPC:            true,
   654  			VerifyServerHostname: true,
   655  			CAFile:               cafile,
   656  			CertFile:             foocert,
   657  			KeyFile:              fookey,
   658  		},
   659  	}
   660  
   661  	agent := &Agent{
   662  		config: agentConfig,
   663  	}
   664  
   665  	newConfig := &Config{
   666  		TLSConfig: &sconfig.TLSConfig{
   667  			EnableHTTP:           true,
   668  			EnableRPC:            true,
   669  			VerifyServerHostname: true,
   670  			CAFile:               cafile,
   671  			CertFile:             foocert2,
   672  			KeyFile:              fookey2,
   673  		},
   674  	}
   675  
   676  	originalKeyloader := agentConfig.TLSConfig.GetKeyLoader()
   677  	assert.NotNil(originalKeyloader)
   678  
   679  	err := agent.Reload(newConfig)
   680  	assert.Nil(err)
   681  	assert.Equal(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   682  	assert.Equal(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   683  	assert.Equal(agent.config.TLSConfig.GetKeyLoader(), originalKeyloader)
   684  }
   685  
   686  func TestServer_Reload_TLS_Certificate_Invalid(t *testing.T) {
   687  	t.Parallel()
   688  	assert := assert.New(t)
   689  
   690  	const (
   691  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   692  		foocert  = "../../helper/tlsutil/testdata/nomad-bad.pem"
   693  		fookey   = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   694  		foocert2 = "invalid_cert_path"
   695  		fookey2  = "invalid_key_path"
   696  	)
   697  
   698  	agentConfig := &Config{
   699  		TLSConfig: &sconfig.TLSConfig{
   700  			EnableHTTP:           true,
   701  			EnableRPC:            true,
   702  			VerifyServerHostname: true,
   703  			CAFile:               cafile,
   704  			CertFile:             foocert,
   705  			KeyFile:              fookey,
   706  		},
   707  	}
   708  
   709  	agent := &Agent{
   710  		config: agentConfig,
   711  	}
   712  
   713  	newConfig := &Config{
   714  		TLSConfig: &sconfig.TLSConfig{
   715  			EnableHTTP:           true,
   716  			EnableRPC:            true,
   717  			VerifyServerHostname: true,
   718  			CAFile:               cafile,
   719  			CertFile:             foocert2,
   720  			KeyFile:              fookey2,
   721  		},
   722  	}
   723  
   724  	err := agent.Reload(newConfig)
   725  	assert.NotNil(err)
   726  	assert.NotEqual(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   727  	assert.NotEqual(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   728  }
   729  
   730  func Test_GetConfig(t *testing.T) {
   731  	assert := assert.New(t)
   732  
   733  	agentConfig := &Config{
   734  		Telemetry:      &Telemetry{},
   735  		Client:         &ClientConfig{},
   736  		Server:         &ServerConfig{},
   737  		ACL:            &ACLConfig{},
   738  		Ports:          &Ports{},
   739  		Addresses:      &Addresses{},
   740  		AdvertiseAddrs: &AdvertiseAddrs{},
   741  		Vault:          &sconfig.VaultConfig{},
   742  		Consul:         &sconfig.ConsulConfig{},
   743  		Sentinel:       &sconfig.SentinelConfig{},
   744  	}
   745  
   746  	agent := &Agent{
   747  		config: agentConfig,
   748  	}
   749  
   750  	actualAgentConfig := agent.GetConfig()
   751  	assert.Equal(actualAgentConfig, agentConfig)
   752  }
   753  
   754  func TestServer_Reload_TLS_WithNilConfiguration(t *testing.T) {
   755  	t.Parallel()
   756  	assert := assert.New(t)
   757  
   758  	logger := testlog.HCLogger(t)
   759  
   760  	agent := &Agent{
   761  		logger: logger,
   762  		config: &Config{},
   763  	}
   764  
   765  	err := agent.Reload(nil)
   766  	assert.NotNil(err)
   767  	assert.Equal(err.Error(), "cannot reload agent with nil configuration")
   768  }
   769  
   770  func TestServer_Reload_TLS_UpgradeToTLS(t *testing.T) {
   771  	t.Parallel()
   772  	assert := assert.New(t)
   773  
   774  	const (
   775  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   776  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   777  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   778  	)
   779  	dir := tmpDir(t)
   780  	defer os.RemoveAll(dir)
   781  
   782  	logger := testlog.HCLogger(t)
   783  
   784  	agentConfig := &Config{
   785  		TLSConfig: &sconfig.TLSConfig{},
   786  	}
   787  
   788  	agent := &Agent{
   789  		logger: logger,
   790  		config: agentConfig,
   791  	}
   792  
   793  	newConfig := &Config{
   794  		TLSConfig: &sconfig.TLSConfig{
   795  			EnableHTTP:           true,
   796  			EnableRPC:            true,
   797  			VerifyServerHostname: true,
   798  			CAFile:               cafile,
   799  			CertFile:             foocert,
   800  			KeyFile:              fookey,
   801  		},
   802  	}
   803  
   804  	err := agent.Reload(newConfig)
   805  	assert.Nil(err)
   806  
   807  	assert.Equal(agent.config.TLSConfig.CAFile, newConfig.TLSConfig.CAFile)
   808  	assert.Equal(agent.config.TLSConfig.CertFile, newConfig.TLSConfig.CertFile)
   809  	assert.Equal(agent.config.TLSConfig.KeyFile, newConfig.TLSConfig.KeyFile)
   810  }
   811  
   812  func TestServer_Reload_TLS_DowngradeFromTLS(t *testing.T) {
   813  	t.Parallel()
   814  	assert := assert.New(t)
   815  
   816  	const (
   817  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   818  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   819  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   820  	)
   821  	dir := tmpDir(t)
   822  	defer os.RemoveAll(dir)
   823  
   824  	logger := testlog.HCLogger(t)
   825  
   826  	agentConfig := &Config{
   827  		TLSConfig: &sconfig.TLSConfig{
   828  			EnableHTTP:           true,
   829  			EnableRPC:            true,
   830  			VerifyServerHostname: true,
   831  			CAFile:               cafile,
   832  			CertFile:             foocert,
   833  			KeyFile:              fookey,
   834  		},
   835  	}
   836  
   837  	agent := &Agent{
   838  		logger: logger,
   839  		config: agentConfig,
   840  	}
   841  
   842  	newConfig := &Config{
   843  		TLSConfig: &sconfig.TLSConfig{},
   844  	}
   845  
   846  	assert.False(agentConfig.TLSConfig.IsEmpty())
   847  
   848  	err := agent.Reload(newConfig)
   849  	assert.Nil(err)
   850  
   851  	assert.True(agentConfig.TLSConfig.IsEmpty())
   852  }
   853  
   854  func TestServer_ShouldReload_ReturnFalseForNoChanges(t *testing.T) {
   855  	t.Parallel()
   856  	assert := assert.New(t)
   857  
   858  	const (
   859  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   860  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   861  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   862  	)
   863  	dir := tmpDir(t)
   864  	defer os.RemoveAll(dir)
   865  
   866  	sameAgentConfig := &Config{
   867  		TLSConfig: &sconfig.TLSConfig{
   868  			EnableHTTP:           true,
   869  			EnableRPC:            true,
   870  			VerifyServerHostname: true,
   871  			CAFile:               cafile,
   872  			CertFile:             foocert,
   873  			KeyFile:              fookey,
   874  		},
   875  	}
   876  
   877  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   878  		c.TLSConfig = &sconfig.TLSConfig{
   879  			EnableHTTP:           true,
   880  			EnableRPC:            true,
   881  			VerifyServerHostname: true,
   882  			CAFile:               cafile,
   883  			CertFile:             foocert,
   884  			KeyFile:              fookey,
   885  		}
   886  	})
   887  	defer agent.Shutdown()
   888  
   889  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   890  	assert.False(shouldReloadAgent)
   891  	assert.False(shouldReloadHTTP)
   892  }
   893  
   894  func TestServer_ShouldReload_ReturnTrueForOnlyHTTPChanges(t *testing.T) {
   895  	t.Parallel()
   896  	require := require.New(t)
   897  
   898  	const (
   899  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   900  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   901  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   902  	)
   903  	dir := tmpDir(t)
   904  	defer os.RemoveAll(dir)
   905  
   906  	sameAgentConfig := &Config{
   907  		TLSConfig: &sconfig.TLSConfig{
   908  			EnableHTTP:           false,
   909  			EnableRPC:            true,
   910  			VerifyServerHostname: true,
   911  			CAFile:               cafile,
   912  			CertFile:             foocert,
   913  			KeyFile:              fookey,
   914  		},
   915  	}
   916  
   917  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   918  		c.TLSConfig = &sconfig.TLSConfig{
   919  			EnableHTTP:           true,
   920  			EnableRPC:            true,
   921  			VerifyServerHostname: true,
   922  			CAFile:               cafile,
   923  			CertFile:             foocert,
   924  			KeyFile:              fookey,
   925  		}
   926  	})
   927  	defer agent.Shutdown()
   928  
   929  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   930  	require.True(shouldReloadAgent)
   931  	require.True(shouldReloadHTTP)
   932  }
   933  
   934  func TestServer_ShouldReload_ReturnTrueForOnlyRPCChanges(t *testing.T) {
   935  	t.Parallel()
   936  	assert := assert.New(t)
   937  
   938  	const (
   939  		cafile  = "../../helper/tlsutil/testdata/ca.pem"
   940  		foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
   941  		fookey  = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   942  	)
   943  	dir := tmpDir(t)
   944  	defer os.RemoveAll(dir)
   945  
   946  	sameAgentConfig := &Config{
   947  		TLSConfig: &sconfig.TLSConfig{
   948  			EnableHTTP:           true,
   949  			EnableRPC:            true,
   950  			VerifyServerHostname: true,
   951  			CAFile:               cafile,
   952  			CertFile:             foocert,
   953  			KeyFile:              fookey,
   954  		},
   955  	}
   956  
   957  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   958  		c.TLSConfig = &sconfig.TLSConfig{
   959  			EnableHTTP:           true,
   960  			EnableRPC:            false,
   961  			VerifyServerHostname: true,
   962  			CAFile:               cafile,
   963  			CertFile:             foocert,
   964  			KeyFile:              fookey,
   965  		}
   966  	})
   967  	defer agent.Shutdown()
   968  
   969  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
   970  	assert.True(shouldReloadAgent)
   971  	assert.False(shouldReloadHTTP)
   972  }
   973  
   974  func TestServer_ShouldReload_ReturnTrueForConfigChanges(t *testing.T) {
   975  	t.Parallel()
   976  	assert := assert.New(t)
   977  
   978  	const (
   979  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
   980  		foocert  = "../../helper/tlsutil/testdata/nomad-foo.pem"
   981  		fookey   = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
   982  		foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
   983  		fookey2  = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
   984  	)
   985  	dir := tmpDir(t)
   986  	defer os.RemoveAll(dir)
   987  
   988  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
   989  		c.TLSConfig = &sconfig.TLSConfig{
   990  			EnableHTTP:           true,
   991  			EnableRPC:            true,
   992  			VerifyServerHostname: true,
   993  			CAFile:               cafile,
   994  			CertFile:             foocert,
   995  			KeyFile:              fookey,
   996  		}
   997  	})
   998  	defer agent.Shutdown()
   999  
  1000  	newConfig := &Config{
  1001  		TLSConfig: &sconfig.TLSConfig{
  1002  			EnableHTTP:           true,
  1003  			EnableRPC:            true,
  1004  			VerifyServerHostname: true,
  1005  			CAFile:               cafile,
  1006  			CertFile:             foocert2,
  1007  			KeyFile:              fookey2,
  1008  		},
  1009  	}
  1010  
  1011  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(newConfig)
  1012  	assert.True(shouldReloadAgent)
  1013  	assert.True(shouldReloadHTTP)
  1014  }
  1015  
  1016  func TestServer_ShouldReload_ReturnTrueForFileChanges(t *testing.T) {
  1017  	t.Parallel()
  1018  	require := require.New(t)
  1019  
  1020  	oldCertificate := `
  1021  	-----BEGIN CERTIFICATE-----
  1022  	MIICrzCCAlagAwIBAgIUN+4rYZ6wqQCIBzYYd0sfX2e8hDowCgYIKoZIzj0EAwIw
  1023  	eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
  1024  	biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
  1025  	GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAgFw0xNjExMTAxOTU2MDBaGA8yMTE2
  1026  	MTAxNzE5NTYwMFoweDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
  1027  	FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwG
  1028  	A1UECxMFTm9tYWQxGDAWBgNVBAMTD3JlZ2lvbkZvby5ub21hZDBZMBMGByqGSM49
  1029  	AgEGCCqGSM49AwEHA0IABOqGSFNjm+EBlLYlxmIP6SQTdX8U/6hbPWObB0ffkEO/
  1030  	CFweeYIVWb3FKNPqYAlhMqg1K0ileD0FbhEzarP0sL6jgbswgbgwDgYDVR0PAQH/
  1031  	BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8E
  1032  	AjAAMB0GA1UdDgQWBBQnMcjU4yI3k0AoMtapACpO+w9QMTAfBgNVHSMEGDAWgBQ6
  1033  	NWr8F5y2eFwqfoQdQPg0kWb9QDA5BgNVHREEMjAwghZzZXJ2ZXIucmVnaW9uRm9v
  1034  	Lm5vbWFkghZjbGllbnQucmVnaW9uRm9vLm5vbWFkMAoGCCqGSM49BAMCA0cAMEQC
  1035  	ICrvzc5NzqhdT/HkazAx5OOUU8hqoptnmhRmwn6X+0y9AiA8bNvMUxHz3ZLjGBiw
  1036  	PLBDC2UaSDqJqiiYpYegLhbQtw==
  1037  	-----END CERTIFICATE-----
  1038  	`
  1039  
  1040  	content := []byte(oldCertificate)
  1041  	dir, err := ioutil.TempDir("", "certificate")
  1042  	if err != nil {
  1043  		t.Fatal(err)
  1044  	}
  1045  	defer os.RemoveAll(dir) // clean up
  1046  
  1047  	tmpfn := filepath.Join(dir, "testcert")
  1048  	err = ioutil.WriteFile(tmpfn, content, 0666)
  1049  	require.Nil(err)
  1050  
  1051  	const (
  1052  		cafile = "../../helper/tlsutil/testdata/ca.pem"
  1053  		key    = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
  1054  	)
  1055  
  1056  	logger := testlog.HCLogger(t)
  1057  
  1058  	agentConfig := &Config{
  1059  		TLSConfig: &sconfig.TLSConfig{
  1060  			EnableHTTP:           true,
  1061  			EnableRPC:            true,
  1062  			VerifyServerHostname: true,
  1063  			CAFile:               cafile,
  1064  			CertFile:             tmpfn,
  1065  			KeyFile:              key,
  1066  		},
  1067  	}
  1068  
  1069  	agent := &Agent{
  1070  		logger: logger,
  1071  		config: agentConfig,
  1072  	}
  1073  	agent.config.TLSConfig.SetChecksum()
  1074  
  1075  	shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(agentConfig)
  1076  	require.False(shouldReloadAgent)
  1077  	require.False(shouldReloadHTTP)
  1078  
  1079  	newCertificate := `
  1080  	-----BEGIN CERTIFICATE-----
  1081  	MIICtTCCAlqgAwIBAgIUQp/L2szbgE4b1ASlPOZMReFE27owCgYIKoZIzj0EAwIw
  1082  	fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
  1083  	biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
  1084  	HDAaBgNVBAMTE2JhZC5ub21hZC5oYXNoaWNvcnAwIBcNMTYxMTEwMjAxMDAwWhgP
  1085  	MjExNjEwMTcyMDEwMDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
  1086  	bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAx
  1087  	DjAMBgNVBAsTBU5vbWFkMRgwFgYDVQQDEw9yZWdpb25CYWQubm9tYWQwWTATBgcq
  1088  	hkjOPQIBBggqhkjOPQMBBwNCAAQk6oXJwlxNrKvl6kpeeR4NJc5EYFI2b3y7odjY
  1089  	u55Jp4sI91JVDqnpyatkyGmavdAWa4t0U6HkeaWqKk16/ZcYo4G7MIG4MA4GA1Ud
  1090  	DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
  1091  	AQH/BAIwADAdBgNVHQ4EFgQUxhzOftFR2L0QAPx8LOuP99WPbpgwHwYDVR0jBBgw
  1092  	FoAUHPDLSgzlHqBEh+c4A7HeT0GWygIwOQYDVR0RBDIwMIIWc2VydmVyLnJlZ2lv
  1093  	bkJhZC5ub21hZIIWY2xpZW50LnJlZ2lvbkJhZC5ub21hZDAKBggqhkjOPQQDAgNJ
  1094  	ADBGAiEAq2rnBeX/St/8i9Cab7Yw0C7pjcaE+mrFYeQByng1Uc0CIQD/o4BrZdkX
  1095  	Nm7QGTRZbUFZTHYZr0ULz08Iaz2aHQ6Mcw==
  1096  	-----END CERTIFICATE-----
  1097  	`
  1098  
  1099  	os.Remove(tmpfn)
  1100  	err = ioutil.WriteFile(tmpfn, []byte(newCertificate), 0666)
  1101  	require.Nil(err)
  1102  
  1103  	newAgentConfig := &Config{
  1104  		TLSConfig: &sconfig.TLSConfig{
  1105  			EnableHTTP:           true,
  1106  			EnableRPC:            true,
  1107  			VerifyServerHostname: true,
  1108  			CAFile:               cafile,
  1109  			CertFile:             tmpfn,
  1110  			KeyFile:              key,
  1111  		},
  1112  	}
  1113  
  1114  	shouldReloadAgent, shouldReloadHTTP = agent.ShouldReload(newAgentConfig)
  1115  	require.True(shouldReloadAgent)
  1116  	require.True(shouldReloadHTTP)
  1117  }
  1118  
  1119  func TestServer_ShouldReload_ShouldHandleMultipleChanges(t *testing.T) {
  1120  	t.Parallel()
  1121  	require := require.New(t)
  1122  
  1123  	const (
  1124  		cafile   = "../../helper/tlsutil/testdata/ca.pem"
  1125  		foocert  = "../../helper/tlsutil/testdata/nomad-foo.pem"
  1126  		fookey   = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
  1127  		foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
  1128  		fookey2  = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
  1129  	)
  1130  	dir := tmpDir(t)
  1131  	defer os.RemoveAll(dir)
  1132  
  1133  	sameAgentConfig := &Config{
  1134  		TLSConfig: &sconfig.TLSConfig{
  1135  			EnableHTTP:           true,
  1136  			EnableRPC:            true,
  1137  			VerifyServerHostname: true,
  1138  			CAFile:               cafile,
  1139  			CertFile:             foocert,
  1140  			KeyFile:              fookey,
  1141  		},
  1142  	}
  1143  
  1144  	agent := NewTestAgent(t, t.Name(), func(c *Config) {
  1145  		c.TLSConfig = &sconfig.TLSConfig{
  1146  			EnableHTTP:           true,
  1147  			EnableRPC:            true,
  1148  			VerifyServerHostname: true,
  1149  			CAFile:               cafile,
  1150  			CertFile:             foocert2,
  1151  			KeyFile:              fookey2,
  1152  		}
  1153  	})
  1154  	defer agent.Shutdown()
  1155  
  1156  	{
  1157  		shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
  1158  		require.True(shouldReloadAgent)
  1159  		require.True(shouldReloadHTTP)
  1160  	}
  1161  
  1162  	err := agent.Reload(sameAgentConfig)
  1163  	require.Nil(err)
  1164  
  1165  	{
  1166  		shouldReloadAgent, shouldReloadHTTP := agent.ShouldReload(sameAgentConfig)
  1167  		require.False(shouldReloadAgent)
  1168  		require.False(shouldReloadHTTP)
  1169  	}
  1170  }
  1171  
  1172  func TestAgent_ProxyRPC_Dev(t *testing.T) {
  1173  	t.Parallel()
  1174  	agent := NewTestAgent(t, t.Name(), nil)
  1175  	defer agent.Shutdown()
  1176  
  1177  	id := agent.client.NodeID()
  1178  	req := &structs.NodeSpecificRequest{
  1179  		NodeID: id,
  1180  		QueryOptions: structs.QueryOptions{
  1181  			Region: agent.server.Region(),
  1182  		},
  1183  	}
  1184  
  1185  	time.Sleep(100 * time.Millisecond)
  1186  
  1187  	var resp cstructs.ClientStatsResponse
  1188  	if err := agent.RPC("ClientStats.Stats", req, &resp); err != nil {
  1189  		t.Fatalf("err: %v", err)
  1190  	}
  1191  }