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