...

Source file src/github.com/emissary-ingress/emissary/v3/cmd/entrypoint/testutil_fake_syntheticauth_test.go

Documentation: github.com/emissary-ingress/emissary/v3/cmd/entrypoint

     1  package entrypoint_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/emissary-ingress/emissary/v3/cmd/entrypoint"
    11  	v3bootstrap "github.com/emissary-ingress/emissary/v3/pkg/api/envoy/config/bootstrap/v3"
    12  	v3cluster "github.com/emissary-ingress/emissary/v3/pkg/api/envoy/config/cluster/v3"
    13  	"github.com/emissary-ingress/emissary/v3/pkg/snapshot/v1"
    14  )
    15  
    16  // This predicate is used to check k8s snapshots for an AuthService matching the provided name and
    17  // namespace.
    18  func HasAuthService(namespace, name string) func(snapshot *snapshot.Snapshot) bool {
    19  	return func(snapshot *snapshot.Snapshot) bool {
    20  		for _, m := range snapshot.Kubernetes.AuthServices {
    21  			if m.Namespace == namespace && m.Name == name {
    22  				return true
    23  			}
    24  		}
    25  		return false
    26  	}
    27  }
    28  
    29  // Tests the synthetic auth generation when a valid AuthService is created.  This AuthService has
    30  // `protocol_version: v3` and should not be replaced by the synthetic AuthService.
    31  func TestSyntheticAuthValid(t *testing.T) {
    32  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
    33  		apiVersion := apiVersion // capture loop variable
    34  		t.Run(apiVersion, func(t *testing.T) {
    35  			t.Setenv("EDGE_STACK", "true")
    36  
    37  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
    38  
    39  			err := f.UpsertYAML(`
    40  ---
    41  apiVersion: getambassador.io/` + apiVersion + `
    42  kind: AuthService
    43  metadata:
    44    name: edge-stack-auth-test
    45    namespace: foo
    46  spec:
    47    auth_service: 127.0.0.1:8500
    48    protocol_version: "v3"
    49    proto: "grpc"
    50  `)
    51  			assert.NoError(t, err)
    52  			f.Flush()
    53  
    54  			// Use the predicate above to check that the snapshot contains the
    55  			// AuthService defined above.  The AuthService has `protocol_version: v3` so
    56  			// it should not be removed/replaced by the synthetic AuthService injected
    57  			// by syntheticauth.go
    58  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
    59  			assert.NoError(t, err)
    60  			assert.NotNil(t, snap)
    61  
    62  			// In edge-stack we should only ever have 1 AuthService.
    63  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
    64  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
    65  
    66  			// Check for an ext_authz cluster name matching the provided AuthService
    67  			// (Http_Filters are harder to check since they always have the same name).
    68  			// The namespace for this extauthz cluster should be foo (since that is the
    69  			// namespace of the valid AuthService above).
    70  			isAuthCluster := func(c *v3cluster.Cluster) bool {
    71  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
    72  			}
    73  
    74  			// Grab the next Envoy config that has an Edge Stack auth cluster on
    75  			// 127.0.0.1:8500
    76  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
    77  				return FindCluster(envoy, isAuthCluster) != nil
    78  			})
    79  			require.NoError(t, err)
    80  
    81  			// Make sure an Envoy Config containing a extauth cluster for the
    82  			// AuthService that was defined.
    83  			assert.NotNil(t, envoyConfig)
    84  		})
    85  	}
    86  }
    87  
    88  // This tests with a provided AuthService that has no protocol_version (which defaults to v2).  It
    89  // should get forcibly overridden to be v3.
    90  func TestSyntheticAuthReplace(t *testing.T) {
    91  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
    92  		apiVersion := apiVersion // capture loop variable
    93  		t.Run(apiVersion, func(t *testing.T) {
    94  			t.Setenv("EDGE_STACK", "true")
    95  
    96  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
    97  
    98  			err := f.UpsertYAML(`
    99  ---
   100  apiVersion: getambassador.io/` + apiVersion + `
   101  kind: AuthService
   102  metadata:
   103    name: edge-stack-auth-test
   104    namespace: foo
   105  spec:
   106    auth_service: 127.0.0.1:8500
   107    proto: "grpc"
   108  `)
   109  			assert.NoError(t, err)
   110  			f.Flush()
   111  
   112  			// The AuthService does not have `protocol_version: v3` so it should be
   113  			// forcibly edited to say `protocol_version: v3` by syntheticauth.go
   114  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   115  			assert.NoError(t, err)
   116  			assert.NotNil(t, snap)
   117  
   118  			// In edge-stack we should only ever have 1 AuthService.
   119  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   120  			// The snapshot should only have the one defined above.
   121  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   122  			// The protocol version should be forcibly set to v3.
   123  			assert.Equal(t, "v3", snap.Kubernetes.AuthServices[0].Spec.ProtocolVersion)
   124  
   125  			// Check for an ext_authz cluster name matching the provided AuthService
   126  			// (Http_Filters are harder to check since they always have the same name).
   127  			// The namespace for this extauthz cluster should be "foo" (since that is
   128  			// the namespace of the AuthService).
   129  			isAuthCluster := func(c *v3cluster.Cluster) bool {
   130  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   131  			}
   132  
   133  			// Grab the next Envoy config that has an Edge Stack auth cluster on
   134  			// 127.0.0.1:8500
   135  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   136  				return FindCluster(envoy, isAuthCluster) != nil
   137  			})
   138  			require.NoError(t, err)
   139  
   140  			// Make sure an Envoy Config containing a extauth cluster for the
   141  			// AuthService that was defined.
   142  			assert.NotNil(t, envoyConfig)
   143  		})
   144  	}
   145  }
   146  
   147  // Tests the synthetic auth generation when an invalid AuthService is created.  This AuthService has
   148  // `protocol_version: v3` and should not be replaced by the synthetic AuthService even though it has
   149  // a bogus value because the bogus field will be dropped when it is loaded and we will be left with
   150  // a valid AuthService.
   151  func TestSyntheticAuthBogusField(t *testing.T) {
   152  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
   153  		apiVersion := apiVersion // capture loop variable
   154  		t.Run(apiVersion, func(t *testing.T) {
   155  			t.Setenv("EDGE_STACK", "true")
   156  
   157  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   158  
   159  			err := f.UpsertYAML(`
   160  ---
   161  apiVersion: getambassador.io/` + apiVersion + `
   162  kind: AuthService
   163  metadata:
   164    name: edge-stack-auth-test
   165    namespace: foo
   166  spec:
   167    auth_service: 127.0.0.1:8500
   168    protocol_version: "v3"
   169    proto: "grpc"
   170    bogus_field: "foo"
   171  `)
   172  			assert.NoError(t, err)
   173  			f.Flush()
   174  
   175  			// Use the predicate above to check that the snapshot contains the
   176  			// AuthService defined above.  The AuthService has `protocol_version: v3` so
   177  			// it should not be removed/replaced by the synthetic AuthService injected
   178  			// by syntheticauth.go
   179  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   180  			assert.NoError(t, err)
   181  			assert.NotNil(t, snap)
   182  
   183  			// In edge-stack we should only ever have 1 AuthService.
   184  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   185  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   186  
   187  			// Check for an ext_authz cluster name matching the provided AuthService
   188  			// (Http_Filters are harder to check since they always have the same name).
   189  			// The namespace for this extauthz cluster should be "foo" (since that is
   190  			// the namespace of the valid AuthService above).
   191  			isAuthCluster := func(c *v3cluster.Cluster) bool {
   192  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   193  			}
   194  
   195  			// Grab the next Envoy config that has an Edge Stack auth cluster on
   196  			// 127.0.0.1:8500
   197  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   198  				return FindCluster(envoy, isAuthCluster) != nil
   199  			})
   200  			require.NoError(t, err)
   201  
   202  			// Make sure an Envoy Config containing a extauth cluster for the
   203  			// AuthService that was defined.
   204  			assert.NotNil(t, envoyConfig)
   205  		})
   206  	}
   207  }
   208  
   209  // Tests the synthetic auth generation when an invalid AuthService (because the protocol_version is
   210  // invalid for the supported enums).  This AuthService should be tossed out an the synthetic
   211  // AuthService should be injected.
   212  func TestSyntheticAuthInvalidProtocolVer(t *testing.T) {
   213  	t.Setenv("EDGE_STACK", "true")
   214  
   215  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   216  
   217  	err := f.UpsertYAML(`
   218  ---
   219  apiVersion: getambassador.io/v2
   220  kind: AuthService
   221  metadata:
   222    name: edge-stack-auth-test
   223    namespace: foo
   224  spec:
   225    auth_service: 127.0.0.1:8500
   226    protocol_version: "vBogus"
   227    proto: "grpc"
   228    bogus_field: "foo"
   229  `)
   230  	assert.NoError(t, err)
   231  	f.Flush()
   232  
   233  	// Use the predicate above to check that the snapshot contains the synthetic AuthService.
   234  	// The AuthService has `protocol_version: v3`, but it has a bogus field so it should not be
   235  	// validated and instead we inject the synthetic AuthService.
   236  	snap, err := f.GetSnapshot(HasAuthService("default", "synthetic_edge_stack_auth"))
   237  	assert.NoError(t, err)
   238  	assert.NotNil(t, snap)
   239  
   240  	// In edge-stack we should only ever have 1 AuthService.
   241  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   242  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   243  	assert.Equal(t, "synthetic_edge_stack_auth", snap.Kubernetes.AuthServices[0].Name)
   244  
   245  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   246  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   247  	// AuthService).
   248  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   249  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_default")
   250  	}
   251  
   252  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   253  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   254  		return FindCluster(envoy, isAuthCluster) != nil
   255  	})
   256  	require.NoError(t, err)
   257  
   258  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   259  	// defined.
   260  	assert.NotNil(t, envoyConfig)
   261  }
   262  
   263  // Tests the synthetic auth generation when an invalid AuthService is created and edited several
   264  // times in succession.  After the config is edited several times, we should see that the final
   265  // result is our provided valid AuthService.  There should not be any duplicate AuthService
   266  // resources, and the synthetic AuthService that gets created when the first invalid AuthService is
   267  // applied should be removed when the final edit makes it a valid AuthService.
   268  func TestSyntheticAuthChurn(t *testing.T) {
   269  	t.Setenv("EDGE_STACK", "true")
   270  
   271  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   272  	f.AutoFlush(true)
   273  
   274  	err := f.UpsertYAML(`
   275  ---
   276  apiVersion: getambassador.io/v3alpha1
   277  kind: AuthService
   278  metadata:
   279    name: edge-stack-auth-test
   280    namespace: foo
   281  spec:
   282    auth_service: 127.0.0.1:8500
   283    proto: "grpc"
   284  `)
   285  	assert.NoError(t, err)
   286  	err = f.UpsertYAML(`
   287  ---
   288  apiVersion: getambassador.io/v3alpha1
   289  kind: AuthService
   290  metadata:
   291    name: edge-stack-auth-test
   292    namespace: foo
   293  spec:
   294    auth_service: 127.0.0.1:8500
   295    protocol_version: "v3"
   296    proto: "grpc"
   297  `)
   298  	assert.NoError(t, err)
   299  	err = f.UpsertYAML(`
   300  ---
   301  apiVersion: getambassador.io/v3alpha1
   302  kind: AuthService
   303  metadata:
   304    name: edge-stack-auth-test
   305    namespace: foo
   306  spec:
   307    auth_service: 127.0.0.1:8500
   308    proto: "grpc"
   309  `)
   310  	assert.NoError(t, err)
   311  	err = f.UpsertYAML(`
   312  ---
   313  apiVersion: getambassador.io/v3alpha1
   314  kind: AuthService
   315  metadata:
   316    name: edge-stack-auth-test
   317    namespace: foo
   318  spec:
   319    auth_service: 127.0.0.1:8500
   320    protocol_version: "v3"
   321    proto: "grpc"
   322  `)
   323  	assert.NoError(t, err)
   324  
   325  	// Use the predicate above to check that the snapshot contains the AuthService defined
   326  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   327  	// by the synthetic AuthService injected by syntheticauth.go
   328  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   329  	assert.NoError(t, err)
   330  	assert.NotNil(t, snap)
   331  
   332  	// In edge-stack we should only ever have 1 AuthService.
   333  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   334  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   335  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   336  
   337  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   338  	// harder to check since they always have the same name).  The namespace for this extauthz
   339  	// cluster should be foo (since that is the namespace of the valid AuthService above)
   340  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   341  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   342  	}
   343  
   344  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   345  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   346  		return FindCluster(envoy, isAuthCluster) != nil
   347  	})
   348  	require.NoError(t, err)
   349  
   350  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was defined
   351  	assert.NotNil(t, envoyConfig)
   352  }
   353  
   354  // Tests the synthetic auth generation by first creating an invalid AuthService and confirming that
   355  // the synthetic AuthService gets injected.  Afterwards, a valid AuthService is applied and we
   356  // expect the synthetic AuthService to be removed in favor of the new valid AuthService.
   357  func TestSyntheticAuthInjectAndRemove(t *testing.T) {
   358  	t.Setenv("EDGE_STACK", "true")
   359  
   360  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   361  	f.AutoFlush(true)
   362  
   363  	// This will cause a synthethic AuthService to be injected.
   364  	err := f.UpsertYAML(`
   365  ---
   366  apiVersion: getambassador.io/v3alpha1
   367  kind: AuthService
   368  metadata:
   369    name: edge-stack-auth-test
   370    namespace: foo
   371  spec:
   372    auth_service: 127.0.0.1:8500
   373    proto: "grpc"
   374    protocol_version: "vBogus"
   375  `)
   376  	assert.NoError(t, err)
   377  
   378  	// Use the predicate above to check that the snapshot contains the synthetic AuthService.
   379  	// The user-provided AuthService is invalid and so it should be ignored and instead we
   380  	// inject the synthetic AuthService.
   381  	snap, err := f.GetSnapshot(HasAuthService("default", "synthetic_edge_stack_auth"))
   382  	assert.NoError(t, err)
   383  	assert.NotNil(t, snap)
   384  
   385  	// We should only have 1 AuthService.
   386  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   387  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   388  	assert.Equal(t, "synthetic_edge_stack_auth", snap.Kubernetes.AuthServices[0].Name)
   389  
   390  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   391  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   392  	// AuthService).
   393  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   394  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_default")
   395  	}
   396  
   397  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   398  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   399  		return FindCluster(envoy, isAuthCluster) != nil
   400  	})
   401  	require.NoError(t, err)
   402  
   403  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   404  	// defined.
   405  	assert.NotNil(t, envoyConfig)
   406  
   407  	// Updating the yaml for that AuthService to include `protocol_version: v3` should make it
   408  	// valid and then remove our synthetic AuthService and allow the now valid AuthService to be
   409  	// used.
   410  	err = f.UpsertYAML(`
   411  ---
   412  apiVersion: getambassador.io/v3alpha1
   413  kind: AuthService
   414  metadata:
   415    name: edge-stack-auth-test
   416    namespace: foo
   417  spec:
   418    auth_service: 127.0.0.1:8500
   419    protocol_version: "v3"
   420    proto: "grpc"
   421  `)
   422  	assert.NoError(t, err)
   423  
   424  	// Use the predicate above to check that the snapshot contains the AuthService defined
   425  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   426  	// by the synthetic AuthService injected by syntheticauth.go
   427  	snap, err = f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   428  	assert.NoError(t, err)
   429  	assert.NotNil(t, snap)
   430  
   431  	// In edge-stack we should only ever have 1 AuthService.
   432  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   433  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   434  
   435  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   436  	// harder to check since they always have the same name).  The namespace for this extauthz
   437  	// cluster should be foo (since that is the namespace of the valid AuthService above).
   438  	isAuthCluster = func(c *v3cluster.Cluster) bool {
   439  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   440  	}
   441  
   442  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   443  	envoyConfig, err = f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   444  		return FindCluster(envoy, isAuthCluster) != nil
   445  	})
   446  	require.NoError(t, err)
   447  
   448  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   449  	// defined.
   450  	assert.NotNil(t, envoyConfig)
   451  }
   452  
   453  // This AuthService points at 127.0.0.1:8500, but it does not have `protocol_version: v3`.  It also
   454  // has additional fields set.  The correct action is to edit the AuthService to say
   455  // `protocol_version: v3`.
   456  func TestSyntheticAuthCopyFields(t *testing.T) {
   457  	t.Setenv("EDGE_STACK", "true")
   458  
   459  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   460  
   461  	err := f.UpsertYAML(`
   462  ---
   463  apiVersion: getambassador.io/v2
   464  kind: AuthService
   465  metadata:
   466    name: edge-stack-auth-test
   467    namespace: foo
   468  spec:
   469    auth_service: 127.0.0.1:8500
   470    proto: "grpc"
   471    timeout_ms: 12345
   472  
   473  `)
   474  	assert.NoError(t, err)
   475  	f.Flush()
   476  
   477  	// Use the predicate above to check that the snapshot contains the AuthService.
   478  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   479  	assert.NoError(t, err)
   480  	assert.NotNil(t, snap)
   481  
   482  	// In edge-stack we should only ever have 1 AuthService.
   483  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   484  	// It should be that user-provided AuthService...
   485  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   486  	assert.Equal(t, int64(12345), snap.Kubernetes.AuthServices[0].Spec.Timeout.Duration.Milliseconds())
   487  	// ... but with `protocol_version: v3` set.
   488  	assert.Equal(t, "v3", snap.Kubernetes.AuthServices[0].Spec.ProtocolVersion)
   489  
   490  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   491  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   492  	// AuthService).
   493  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   494  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   495  	}
   496  
   497  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   498  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   499  		return FindCluster(envoy, isAuthCluster) != nil
   500  	})
   501  	require.NoError(t, err)
   502  
   503  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   504  	// defined.
   505  	assert.NotNil(t, envoyConfig)
   506  }
   507  
   508  // This AuthService does not point at 127.0.0.1:8500, we leave it alone rather than adding a
   509  // synthetic one.
   510  func TestSyntheticAuthCustomAuthService(t *testing.T) {
   511  	t.Setenv("EDGE_STACK", "true")
   512  
   513  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   514  
   515  	err := f.UpsertYAML(`
   516  ---
   517  apiVersion: getambassador.io/v2
   518  kind: AuthService
   519  metadata:
   520    name: edge-stack-auth-test
   521    namespace: foo
   522  spec:
   523    auth_service: dummy-service
   524    proto: "grpc"
   525    protocol_version: "v3"
   526  `)
   527  
   528  	assert.NoError(t, err)
   529  	f.Flush()
   530  
   531  	// Use the predicate above to check that the snapshot contains the AuthService defined
   532  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   533  	// by the synthetic AuthService injected by syntheticauth.go
   534  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   535  	assert.NoError(t, err)
   536  	assert.NotNil(t, snap)
   537  
   538  	// In edge-stack we should only ever have 1 AuthService.
   539  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   540  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   541  
   542  	for _, authService := range snap.Kubernetes.AuthServices {
   543  		assert.Equal(t, "dummy-service", authService.Spec.AuthService)
   544  	}
   545  
   546  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   547  	// harder to check since they always have the same name).  the namespace for this extauthz
   548  	// cluster should be foo (since that is the namespace of the valid AuthService above).
   549  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   550  		return strings.Contains(c.Name, "cluster_extauth_dummy_service_foo")
   551  	}
   552  
   553  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   554  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   555  		return FindCluster(envoy, isAuthCluster) != nil
   556  	})
   557  	require.NoError(t, err)
   558  
   559  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   560  	// defined.
   561  	assert.NotNil(t, envoyConfig)
   562  }
   563  
   564  // When deciding if we need to inject a synthetic AuthService or not, we need to be able to reliably
   565  // determine if that AuthService points at a localhost:8500 or not.
   566  func TestIsLocalhost8500(t *testing.T) {
   567  	t.Parallel()
   568  
   569  	type subtest struct {
   570  		inputAddr string
   571  		expected  bool
   572  	}
   573  
   574  	subtests := []subtest{
   575  		{inputAddr: "127.0.0.1:8500", expected: true},
   576  		{inputAddr: "localhost:8500", expected: true},
   577  		{inputAddr: "127.1.2.3:8500", expected: true},
   578  		// IPv6:
   579  		{inputAddr: "http://[0::1]:8500", expected: true},
   580  		{inputAddr: "http://[0:0:0::1]:8500", expected: true},
   581  		{inputAddr: "http://[::0:0:0:1]:8500", expected: true},
   582  
   583  		{inputAddr: "127.0.0.1:850", expected: false},
   584  		{inputAddr: "127.0.0.1:8080", expected: false},
   585  		{inputAddr: "192.168.2.10:8500", expected: false},
   586  		{inputAddr: "", expected: false},
   587  		// IPv6:
   588  		{inputAddr: "http://[0::1]:8400", expected: false},
   589  		{inputAddr: "http://[0::2]:8500", expected: false},
   590  		{inputAddr: "http://[0::2]:8080", expected: false},
   591  		{inputAddr: "http://[0:0:0::2]:8500", expected: false},
   592  		{inputAddr: "http://[0:0:0::1]:8080", expected: false},
   593  		{inputAddr: "http://[::0:0:0:2]:8500", expected: false},
   594  		{inputAddr: "http://[::0:0:0:2]:8080", expected: false},
   595  	}
   596  
   597  	for _, subtest := range subtests {
   598  		subtest := subtest // capture loop variable
   599  		t.Run(subtest.inputAddr, func(t *testing.T) {
   600  			t.Parallel()
   601  			res := entrypoint.IsLocalhost8500(subtest.inputAddr)
   602  			assert.Equal(t, subtest.expected, res)
   603  		})
   604  	}
   605  }
   606  

View as plain text